Added a FontDemo replacement, contributed by Mikael Konradson.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@17745 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2006-06-06 19:40:16 +00:00
parent 3c2793fcc1
commit b765295970
10 changed files with 1238 additions and 0 deletions

View File

@ -11,6 +11,7 @@ SubInclude HAIKU_TOP src apps deskbar ;
SubInclude HAIKU_TOP src apps deskcalc ; SubInclude HAIKU_TOP src apps deskcalc ;
SubInclude HAIKU_TOP src apps diskprobe ; SubInclude HAIKU_TOP src apps diskprobe ;
SubInclude HAIKU_TOP src apps expander ; SubInclude HAIKU_TOP src apps expander ;
SubInclude HAIKU_TOP src apps fontdemo ;
SubInclude HAIKU_TOP src apps glteapot ; SubInclude HAIKU_TOP src apps glteapot ;
SubInclude HAIKU_TOP src apps installer ; SubInclude HAIKU_TOP src apps installer ;
SubInclude HAIKU_TOP src apps magnify ; SubInclude HAIKU_TOP src apps magnify ;

View File

@ -0,0 +1,498 @@
/*
* Copyright 2006, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Mikael Konradson, mikael.konradson@gmail.com
*/
#include "ControlView.h"
#include "messages.h"
#include <Button.h>
#include <CheckBox.h>
#include <Menu.h>
#include <MenuField.h>
#include <MenuItem.h>
#include <MessageRunner.h>
#include <Messenger.h>
#include <Slider.h>
#include <String.h>
#include <TextControl.h>
#include <Window.h>
#include <stdio.h>
ControlView::ControlView(BRect rect)
: BView(rect, "ControlView", B_FOLLOW_ALL, B_WILL_DRAW | B_NAVIGABLE_JUMP),
fMessenger(NULL),
fMessageRunner(NULL),
fTextControl(NULL),
fFontMenuField(NULL),
fFontsizeSlider(NULL),
fShearSlider(NULL),
fRotationSlider(NULL),
fSpacingSlider(NULL),
fOutlineSlider(NULL),
fAliasingCheckBox(NULL),
fBoundingboxesCheckBox(NULL),
fCyclingFontButton(NULL),
fFontFamilyMenu(NULL),
fCycleFonts(false),
fFontStyleindex(0)
{
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
}
ControlView::~ControlView()
{
delete fMessenger;
delete fMessageRunner;
}
void
ControlView::AttachedToWindow()
{
BRect rect(Bounds());
rect.InsetBySelf(10, 0);
rect.bottom = rect.top + 18;
rect.OffsetBy(0, 11);
float offsetX = 0;
float offsetY = 0;
fTextControl = new BTextControl(rect, "TextInput", "Text:", "Haiku, inc.", NULL);
fTextControl->SetDivider(29.0);
fTextControl->SetModificationMessage(new BMessage(TEXT_CHANGED_MSG));
AddChild(fTextControl);
rect.OffsetBy(0.0, 27.0);
_AddFontMenu(rect);
rect.OffsetBy(0.0, 29.0);
fFontsizeSlider = new BSlider(rect, "Fontsize", "Size: 50", NULL, 4, 360);
fFontsizeSlider->SetModificationMessage(new BMessage(FONTSIZE_MSG));
fFontsizeSlider->SetValue(50.0);
AddChild(fFontsizeSlider);
// Get the preferred size for the sliders
fFontsizeSlider->GetPreferredSize(&offsetY, &offsetX);
offsetX += 1;
rect.OffsetBy(0.0, offsetX);
fShearSlider = new BSlider(rect, "Shear", "Shear: 90", NULL, 45, 135);
fShearSlider->SetModificationMessage(new BMessage(FONTSHEAR_MSG));
fShearSlider->SetValue(90.0);
AddChild(fShearSlider);
rect.OffsetBy(0.0, offsetX);
fRotationSlider = new BSlider(rect, "Rotation", "Rotation: 0", NULL, 0, 360);
fRotationSlider->SetModificationMessage( new BMessage(ROTATION_MSG));
fRotationSlider->SetValue(0.0);
AddChild(fRotationSlider);
rect.OffsetBy(0.0, offsetX);
fSpacingSlider = new BSlider(rect, "Spacing", "Spacing: 0", NULL, -5, 50);
fSpacingSlider->SetModificationMessage(new BMessage(SPACING_MSG));
fSpacingSlider->SetValue(0.0);
AddChild(fSpacingSlider);
rect.OffsetBy(0.0, offsetX);
fOutlineSlider = new BSlider(rect, "Outline", "Outline:", NULL, 0, 20);
fOutlineSlider->SetModificationMessage(new BMessage(OUTLINE_MSG));
AddChild(fOutlineSlider);
rect.OffsetBy(0.0, offsetX);
fAliasingCheckBox = new BCheckBox(rect, "Aliasing", "Anti-aliased text",
new BMessage(ALIASING_MSG));
fAliasingCheckBox->SetValue(B_CONTROL_ON);
AddChild(fAliasingCheckBox);
rect.OffsetBy(0.0, 22);
fBoundingboxesCheckBox = new BCheckBox(rect, "BoundingBoxes", "Bounding boxes",
new BMessage(BOUNDING_BOX_MSG));
AddChild(fBoundingboxesCheckBox);
rect.OffsetBy(0.0, 22.0);
fCyclingFontButton = new BButton(rect, "Cyclefonts", "Cycle Fonts",
new BMessage(CYCLING_FONTS_MSG));
AddChild(fCyclingFontButton);
fTextControl->SetTarget(this);
fFontsizeSlider->SetTarget(this);
fShearSlider->SetTarget(this);
fRotationSlider->SetTarget(this);
fSpacingSlider->SetTarget(this);
fOutlineSlider->SetTarget(this);
fAliasingCheckBox->SetTarget(this);
fBoundingboxesCheckBox->SetTarget(this);
fCyclingFontButton->SetTarget(this);
}
void
ControlView::Draw(BRect updateRect)
{
BRect rect(Bounds());
SetHighColor(tint_color(ViewColor(), B_LIGHTEN_2_TINT));
StrokeLine(rect.LeftTop(), rect.RightTop());
StrokeLine(rect.LeftTop(), rect.LeftBottom());
SetHighColor(tint_color(ViewColor(), B_DARKEN_2_TINT));
StrokeLine(rect.LeftBottom(), rect.RightBottom());
StrokeLine(rect.RightBottom(), rect.RightTop());
}
void
ControlView::MessageReceived(BMessage* msg)
{
if (!fMessenger) {
BView::MessageReceived(msg);
return;
}
switch (msg->what) {
case TEXT_CHANGED_MSG:
{
BMessage fontMsg(TEXT_CHANGED_MSG);
fontMsg.AddString("_text", fTextControl->Text());
fMessenger->SendMessage(&fontMsg);
break;
}
case FONTSTYLE_CHANGED_MSG:
_UpdateAndSendStyle(msg);
break;
case FONTFAMILY_CHANGED_MSG:
_UpdateAndSendFamily(msg);
break;
case FONTSIZE_MSG:
{
char buff[256];
sprintf(buff, "Size: %d", static_cast<int>(fFontsizeSlider->Value()));
fFontsizeSlider->SetLabel(buff);
BMessage msg(FONTSIZE_MSG);
msg.AddFloat("_size", static_cast<float>(fFontsizeSlider->Value()));
fMessenger->SendMessage(&msg);
break;
}
case FONTSHEAR_MSG:
{
char buff[256];
sprintf(buff, "Shear: %d", static_cast<int>(fShearSlider->Value()));
fShearSlider->SetLabel(buff);
BMessage msg(FONTSHEAR_MSG);
msg.AddFloat("_shear", static_cast<float>(fShearSlider->Value()));
fMessenger->SendMessage(&msg);
break;
}
case ROTATION_MSG:
{
char buff[256];
sprintf(buff, "Rotation: %d", static_cast<int>(fRotationSlider->Value()));
fRotationSlider->SetLabel(buff);
BMessage msg(ROTATION_MSG);
msg.AddFloat("_rotation", static_cast<float>(fRotationSlider->Value()));
fMessenger->SendMessage(&msg);
break;
}
case SPACING_MSG:
{
char buff[256];
sprintf(buff, "Spacing: %d", (int)fSpacingSlider->Value());
fSpacingSlider->SetLabel(buff);
BMessage msg(SPACING_MSG);
msg.AddFloat("_spacing", static_cast<float>(fSpacingSlider->Value()));
fMessenger->SendMessage(&msg);
break;
}
case ALIASING_MSG:
{
BMessage msg(ALIASING_MSG);
msg.AddBool("_aliased", static_cast<bool>(fAliasingCheckBox->Value()));
fMessenger->SendMessage(&msg);
break;
}
case BOUNDING_BOX_MSG:
{
BMessage msg(BOUNDING_BOX_MSG);
msg.AddBool("_boundingbox", static_cast<bool>(fBoundingboxesCheckBox->Value()));
fMessenger->SendMessage(&msg);
break;
}
case OUTLINE_MSG:
{
int8 outlineVal = (int8)fOutlineSlider->Value();
char buff[256];
sprintf(buff, "Outline: %d", outlineVal);
fOutlineSlider->SetLabel(buff);
fAliasingCheckBox->SetEnabled(outlineVal < 1);
fBoundingboxesCheckBox->SetEnabled(outlineVal < 1);
BMessage msg(OUTLINE_MSG);
msg.AddInt8("_outline", outlineVal);
fMessenger->SendMessage(&msg);
break;
}
case CYCLING_FONTS_MSG:
{
fCyclingFontButton->SetLabel(fCycleFonts ? "Cycle Fonts" : "Stop Cycling");
fCycleFonts = !fCycleFonts;
if (fCycleFonts) {
delete fMessageRunner;
fMessageRunner = new BMessageRunner(this,
new BMessage(CYCLING_FONTS_UPDATE_MSG), 360000*2, -1);
} else {
delete fMessageRunner;
fMessageRunner = NULL;
fFontStyleindex = 0;
// Delete our MessageRunner and reset the style index
}
break;
}
case CYCLING_FONTS_UPDATE_MSG:
{
int32 familyindex = -1;
BMenuItem* currentFamilyItem = fFontFamilyMenu->FindMarked();
if (currentFamilyItem) {
familyindex = fFontFamilyMenu->IndexOf(currentFamilyItem);
const int32 installedStyles = count_font_styles(
const_cast<char*>(currentFamilyItem->Label()));
BMenu* submenu = currentFamilyItem->Submenu();
if (submenu) {
BMenuItem* markedStyle = submenu->FindMarked();
fFontStyleindex = submenu->IndexOf(markedStyle);
}
if (fFontStyleindex < installedStyles - 1)
fFontStyleindex++;
else {
fFontStyleindex = 0;
if (familyindex < count_font_families())
familyindex++;
else
familyindex = 0;
}
BMenuItem* newFontFamilyItem = fFontFamilyMenu->ItemAt(familyindex);
BMenuItem* newstyleitem = submenu->ItemAt(fFontStyleindex);
if (newFontFamilyItem && newstyleitem) {
if (msg->AddString("_style", newstyleitem->Label()) != B_OK
|| msg->AddString("_family", newFontFamilyItem->Label()) != B_OK) {
printf("Failed to add _style or family to the message\n");
return;
}
printf("InstalledStyles(%ld), Font(%s), Style(%s)\n",
installedStyles, newFontFamilyItem->Label(),
newstyleitem->Label());
_UpdateAndSendStyle(msg);
}
}
break;
}
default:
BView::MessageReceived(msg);
}
}
void
ControlView::SetTarget(BHandler* handler)
{
delete fMessenger;
fMessenger = new BMessenger(handler);
}
void
ControlView::_UpdateFontmenus(bool setInitialfont)
{
BFont font;
BMenu* stylemenu = NULL;
font_family fontFamilyName, currentFamily;
font_style fontStyleName, currentStyle;
GetFont(&font);
font.GetFamilyAndStyle(&currentFamily, &currentStyle);
const int32 fontfamilies = count_font_families();
fFontFamilyMenu->RemoveItems(0, fFontFamilyMenu->CountItems(), true);
for (int32 i = 0; i < fontfamilies; i++) {
if (get_font_family(i, &fontFamilyName) == B_OK) {
stylemenu = new BMenu(fontFamilyName);
const int32 styles = count_font_styles(fontFamilyName);
BMessage* familyMsg = new BMessage(FONTFAMILY_CHANGED_MSG);
familyMsg->AddString("_family", fontFamilyName);
BMenuItem* familyItem = new BMenuItem(stylemenu, familyMsg);
fFontFamilyMenu->AddItem(familyItem);
for (int32 j = 0; j < styles; j++) {
if (get_font_style(fontFamilyName, j, &fontStyleName) == B_OK) {
BMessage* fontMsg = new BMessage(FONTSTYLE_CHANGED_MSG);
fontMsg->AddString("_family", fontFamilyName);
fontMsg->AddString("_style", fontStyleName);
BMenuItem* styleItem = new BMenuItem(fontStyleName, fontMsg);
styleItem->SetMarked(false);
// setInitialfont is used when we attach the FontField
if (!strcmp(fontStyleName, currentStyle)
&& !strcmp(fontFamilyName, currentFamily)
&& setInitialfont) {
styleItem->SetMarked(true);
familyItem->SetMarked(true);
BString string;
string << currentFamily << " " << currentStyle;
if (fFontMenuField)
fFontMenuField->MenuItem()->SetLabel(string.String());
}
stylemenu->AddItem(styleItem);
}
}
}
stylemenu->SetRadioMode(true);
stylemenu->SetTargetForItems(this);
}
fFontFamilyMenu->SetLabelFromMarked(true);
fFontFamilyMenu->SetTargetForItems(this);
}
void
ControlView::_AddFontMenu(BRect rect)
{
fFontFamilyMenu = new BMenu("fontfamlilymenu");
_UpdateFontmenus(true);
fFontMenuField = new BMenuField(rect, "FontMenuField", "Font:", fFontFamilyMenu, true);
fFontMenuField->SetDivider(30.0);
AddChild(fFontMenuField);
}
void
ControlView::_UpdateAndSendFamily(const BMessage* message)
{
_DeselectOldItems();
const char* family;
font_style style;
if (message->FindString("_family", &family) == B_OK) {
printf("Family:%s\n\n", family);
BMenuItem* markedItem = fFontFamilyMenu->FindItem(family);
if (!markedItem)
return;
markedItem->SetMarked(true);
get_font_style(font_family(family), 0, &style);
BString string;
string << family << " " << style;
if (fFontMenuField)
fFontMenuField->MenuItem()->SetLabel(string.String());
BMenu* submenu = markedItem->Submenu();
if (submenu) {
BMenuItem* styleItem = submenu->FindItem(style);
if (styleItem && !styleItem->IsMarked())
styleItem->SetMarked(true);
}
BMessage fontMsg(FONTFAMILY_CHANGED_MSG);
if (fontMsg.AddMessage("_fontMessage", message) == B_OK)
fMessenger->SendMessage(&fontMsg);
}
}
void
ControlView::_UpdateAndSendStyle(const BMessage* message)
{
_DeselectOldItems();
const char* style;
const char* family;
if (message->FindString("_style", &style) == B_OK
&& message->FindString("_family", &family) == B_OK) {
BMenuItem* familyItem = fFontFamilyMenu->FindItem(family);
if (familyItem && !familyItem->IsMarked()) {
familyItem->SetMarked(true);
BMenu* submenu = familyItem->Submenu();
if (submenu) {
BMenuItem* styleItem = submenu->FindItem(style);
if (styleItem && !styleItem->IsMarked())
styleItem->SetMarked(true);
}
}
BString string;
string << family << " " << style;
if (fFontMenuField)
fFontMenuField->MenuItem()->SetLabel(string.String());
}
BMessage fontMsg(FONTSTYLE_CHANGED_MSG);
if (fontMsg.AddMessage("_fontMessage", message) == B_OK)
fMessenger->SendMessage(&fontMsg);
}
void
ControlView::_DeselectOldItems()
{
BMenuItem* oldItem = fFontFamilyMenu->FindMarked();
if (oldItem) {
oldItem->SetMarked(false);
BMenu* submenu = oldItem->Submenu();
if (submenu) {
BMenuItem* marked = submenu->FindMarked();
if (marked)
marked->SetMarked(false);
}
}
}

View File

@ -0,0 +1,63 @@
/*
* Copyright 2006, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Mikael Konradson, mikael.konradson@gmail.com
*/
#ifndef CONTROL_VIEW_H
#define CONTROL_VIEW_H
#include <View.h>
class BButton;
class BCheckBox;
class BHandler;
class BLooper;
class BMenu;
class BMenuField;
class BMessageRunner;
class BMessenger;
class BSlider;
class BTextControl;
class ControlView : public BView {
public:
ControlView(BRect rect);
virtual ~ControlView();
virtual void AttachedToWindow();
virtual void Draw(BRect updateRect);
virtual void MessageReceived(BMessage* message);
void SetTarget(BHandler* handler);
private:
void _AddFontMenu(BRect rect);
void _UpdateFontmenus(bool setInitialfont = false);
void _DeselectOldItems();
void _UpdateAndSendFamily(const BMessage* message);
void _UpdateAndSendStyle(const BMessage* message);
BMessenger* fMessenger;
BMessageRunner* fMessageRunner;
BTextControl* fTextControl;
BMenuField* fFontMenuField;
BSlider* fFontsizeSlider;
BSlider* fShearSlider;
BSlider* fRotationSlider;
BSlider* fSpacingSlider;
BSlider* fOutlineSlider;
BCheckBox* fAliasingCheckBox;
BCheckBox* fBoundingboxesCheckBox;
BButton* fCyclingFontButton;
BMenu* fFontFamilyMenu;
bool fCycleFonts;
int32 fFontStyleindex;
};
#endif // CONTROL_VIEW_H

View File

@ -0,0 +1,62 @@
/*
* Copyright 2006, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Mikael Konradson, mikael.konradson@gmail.com
*/
#include "FontDemo.h"
#include "FontDemoView.h"
#include "ControlView.h"
#include <Window.h>
FontDemo::FontDemo()
: BApplication("application/x-vnd.Haiku-FontDemo")
{
}
FontDemo::~FontDemo()
{
}
void
FontDemo::ReadyToRun()
{
// Create the demo window where we draw the string
BWindow* demoWindow = new BWindow(BRect(80, 30, 490, 300), "FontDemo",
B_TITLED_WINDOW, B_ASYNCHRONOUS_CONTROLS | B_QUIT_ON_WINDOW_CLOSE);
FontDemoView* demoView = new FontDemoView(demoWindow->Bounds());
demoWindow->AddChild(demoView);
BWindow* controlWindow = new BWindow(BRect(500,30, 700, 352), "Controls",
B_FLOATING_WINDOW_LOOK, B_FLOATING_APP_WINDOW_FEEL,
B_NOT_CLOSABLE | B_NOT_ZOOMABLE | B_NOT_RESIZABLE | B_ASYNCHRONOUS_CONTROLS);
ControlView* controlView = new ControlView(controlWindow->Bounds());
controlWindow->AddChild(controlView);
controlView->SetTarget(demoView);
demoWindow->Show();
controlWindow->Show();
}
// #pragma mark -
int
main()
{
FontDemo fontdemo;
fontdemo.Run();
return 0;
}

View File

@ -0,0 +1,23 @@
/*
* Copyright 2006, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Mikael Konradson, mikael.konradson@gmail.com
*/
#ifndef FONT_DEMO_H
#define FONT_DEMO_H
#include <Application.h>
class FontDemo : public BApplication {
public:
FontDemo();
virtual ~FontDemo();
virtual void ReadyToRun();
};
#endif // FONT_DEMO_H

View File

@ -0,0 +1,76 @@
/*
* FontDemo
*/
resource app_signature "application/x-vnd.Haiku-FontDemo";
resource app_flags B_SINGLE_LAUNCH;
resource app_version {
major = 1,
middle = 0,
minor = 0,
/* 0 = development 1 = alpha 2 = beta
3 = gamma 4 = golden master 5 = final */
variety = 1,
internal = 0,
short_info = "FontDemo",
long_info = "FontDemo 1.0.0 ©2006 Haiku"
};
resource large_icon array {
$"FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
$"FFFFFFFFFFFFFFFFFFFFFFFF008C8C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
$"FFFFFFFFFFFFFFFFFFFFFF008C8C8C8C8C0000FFFFFFFFFFFFFFFFFFFFFFFFFF"
$"FFFFFFFFFFFFFFFFFFFF008C8C8C8C8C8C8C6600FFFFFFFFFFFFFFFFFFFFFFFF"
$"FFFFFFFFFFFFFFFFFF008C8C8C8C8C8C8C662101FFFFFFFFFFFFFFFFFFFFFFFF"
$"FFFFFFFFFFFFFFFF008C8C8C8C8C8C8C6621212000FFFFFFFFFFFFFFFFFFFFFF"
$"FFFFFFFFFFFFFF0066668C8C8C8C8C662121202101FFFFFFFFFFFFFFFFFFFFFF"
$"FFFFFFFFFFFFFF00B2B266668C8C66212120212129FFFFFFFFFFFFFFFFFFFFFF"
$"FFFFFFFFFFFF00B2B2B2B2B2666621212021212000FFFFFFFFFFFFFFFFFFFFFF"
$"FFFFFFFFFFFF00B2B2B2B2B2B28C2121202121202100FFFFFFFFFFFFFFFFFFFF"
$"FFFFFFFFFFFF00B2B2B2B2B2B2B28C21212021212000FFFFFFFFFFFFFFFFFFFF"
$"FFFFFFFFFF00B2B2B2B20000B2B28C21212021212000FFFFFFFFFFFFFFFFFFFF"
$"FFFFFFFFFF00B2B2B2B20000B2B28C21212021212000FFFFFFFFFFFFFFFFFFFF"
$"FFFFFFFF00B2B2B2B2002100B2B28C2121202121202100FFFFFFFFFFFFFFFFFF"
$"FFFFFFFF00B2B2B2B2002100B2B2B28C21212021212000FFFFFFFFFFFFFFFFFF"
$"FFFFFF00B2B2B2B20021218C00B2B28C21212021212000FFFFFFFFFFFFFFFFFF"
$"FFFFFF00B2B2B2B200008C8C00B2B28C21212021212000FFFFFFFFFFFFFFFFFF"
$"FFFF00B2B2B2B2B2B2B2000000B2B28C2121202121202100FFFFFFFFFFFFFFFF"
$"FFFF00B2B2B2B2B2B2B2B2B200B2B2B28C21212021212000FFFFFFFFFFFFFFFF"
$"FFFF00B2B2B20000B2B2B2B2B2B2B2B28C21212021212000FFFFFFFFFFFFFFFF"
$"FF00B2B2B2B200210000B2B2B2B2B2B28C21212021212000FFFFFFFFFFFFFFFF"
$"FF00B2B2B2B2002121200000B2B2B2B28C2121202121202100FFFFFFFFFFFFFF"
$"00B2B2B2B200212120000E0F0000B2B2B28C21212021212000FFFFFFFFFFFFFF"
$"0000B2B2B2002121290E0F0F0F00B2B2B28C21212021212000FFFFFFFFFFFFFF"
$"FFFF0000000021000E0F0F0F0F00B2B2B28C21212021212021000FFFFFFFFFFF"
$"FFFFFFFF0000000E0F0F0F0F0F0F00B2B28C21212021212021000F0F0EFFFFFF"
$"FFFFFFFFFFFFFFFFFFFFFFFFFFFF00B2B2B28C212120212120000E0F0F0F0FFF"
$"FFFFFFFFFFFFFFFFFFFFFFFFFFFF00B2B2B28C2121202121290E0F0F0F0F0FFF"
$"FFFFFFFFFFFFFFFFFFFFFFFFFFFF00B2B2B28C21212021000F0E0F0F0F0FFFFF"
$"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00B2B2B28C2121290E0F0F0F0F0FFFFFFF"
$"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000B28C21000F0E0F0F0F0FFFFFFFFF"
$"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000E0F0F0F0F0FFFFFFFFFFF"
};
resource mini_icon array {
$"FFFFFFFFFFFF0000FFFFFFFFFFFFFFFF"
$"FFFFFFFFFF008C8C0000FFFFFFFFFFFF"
$"FFFFFFFF00668C8C6600FFFFFFFFFFFF"
$"FFFFFF00B2B26666212129FFFFFFFFFF"
$"FFFFFF00B2B2B28C212129FFFFFFFFFF"
$"FFFF00B2B200B28C212129FFFFFFFFFF"
$"FFFF00B2B200B28C212129FFFFFFFFFF"
$"FF00B2B2006600B28C212129FFFFFFFF"
$"FF00B2B2000000B28C212129FFFFFFFF"
$"00B2B200B2B200B28C212129FFFFFFFF"
$"00B2B2000000B2B28C212129FFFFFFFF"
$"00B20021000E29B2B28C212100FFFFFF"
$"FF0000000E0F0000B28C2121290F0FFF"
$"FFFFFFFFFFFFFF00B28C2121290E0F0F"
$"FFFFFFFFFFFFFF00B28C21000F0E0FFF"
$"FFFFFFFFFFFFFFFF0000000E0F0FFFFF"
};

View File

@ -0,0 +1,405 @@
/*
* Copyright 2006, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Mikael Konradson, mikael.konradson@gmail.com
*/
#include "FontDemoView.h"
#include "messages.h"
#include <Bitmap.h>
#include <Font.h>
#include <Message.h>
#include <Shape.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
FontDemoView::FontDemoView(BRect rect)
: BView(rect, "FontDemoView", B_FOLLOW_ALL, B_WILL_DRAW | B_FRAME_EVENTS),
fBitmap(NULL),
fBufferView(NULL),
fString(NULL),
fOutLineLevel(0),
fBoundingBoxes(false),
fDrawShapes(false)
{
SetViewColor(B_TRANSPARENT_COLOR);
SetString("Haiku, inc.");
SetFontSize(50.0);
SetAntialiasing(true);
_NewBitmap(Bounds());
}
FontDemoView::~FontDemoView()
{
free(fString);
free(fShapes);
fBitmap->Lock();
delete fBitmap;
}
void
FontDemoView::FrameResized(float width, float height)
{
// TODO: We shouldnt invalidate the whole view when bounding boxes are working as wanted
Invalidate(/*fBoxRegion.Frame()*/);
BView::FrameResized(width, height);
}
void
FontDemoView::Draw(BRect updateRect)
{
BRect rect = Bounds();
fBufferView = _GetView(rect);
_DrawView(fBufferView);
fBufferView->Sync();
DrawBitmap(fBitmap, rect);
fBitmap->Unlock();
}
void
FontDemoView::_DrawView(BView* view)
{
if (!view)
return;
BRect rect = view->Bounds();
view->SetHighColor(255, 255, 255);
view->FillRect(rect);
if (!fString)
return;
view->SetFont(&fFont, B_FONT_ALL);
const size_t size = strlen(fString);
BRect boundBoxes[size];
if (OutLineLevel())
fFont.GetGlyphShapes(fString, size, fShapes);
else
fFont.GetBoundingBoxesAsGlyphs(fString, size, B_SCREEN_METRIC, boundBoxes);
float escapementArray[size];
//struct escapement_delta escapeDeltas[size];
struct edge_info edgeInfo[size];
/*
for (size_t j = 0; j < size; j++) {
escapeDeltas[j].nonspace = 0.0f;
escapeDeltas[j].space = 0.0f;
}
*/
fFont.GetEdges(fString, size, edgeInfo);
fFont.GetEscapements(fString, size, /*escapeDeltas,*/ escapementArray);
font_height fh;
fFont.GetHeight(&fh);
float xCoordArray[size];
float yCoordArray[size];
float yCoord = (rect.Height() + fh.ascent - fh.descent) / 2;
float xCoord = -rect.Width() / 2;
const float xCenter = xCoord * -1;
const float r = Rotation() * (PI/180.0);
const float cosinus = cos(r);
const float sinus = -sin(r);
// When the bounding boxes workes properly we will invalidate only the
// region area instead of the whole view.
fBoxRegion.MakeEmpty();
for (size_t i = 0; i < size; i++) {
xCoordArray[i] = 0.0f;
yCoordArray[i] = 0.0f;
const float height = boundBoxes[i].Height();
const float width = boundBoxes[i].Width();
yCoordArray[i] = sinus * (xCoord - xCoordArray[i]);
xCoordArray[i] = cosinus * xCoord;
xCoordArray[i] += xCenter;
yCoordArray[i] += yCoord;
boundBoxes[i].left = xCoordArray[i] + edgeInfo[i].left * FontSize();
boundBoxes[i].right = boundBoxes[i].left + width;
boundBoxes[i].bottom = yCoordArray[i];
boundBoxes[i].top = boundBoxes[i].bottom - height;
if (OutLineLevel()) {
view->MovePenTo(xCoordArray[i], yCoordArray[i]);
view->SetHighColor(ui_color(B_PANEL_BACKGROUND_COLOR));
view->FillShape(fShapes[i]);
view->SetPenSize(OutLineLevel());
view->SetHighColor(0, 0, 0);
view->StrokeShape(fShapes[i]);
} else {
view->SetHighColor(0, 0, 0);
view->SetDrawingMode(B_OP_OVER);
view->DrawChar(fString[i], BPoint(xCoordArray[i], yCoordArray[i]));
}
if (BoundingBoxes() && !OutLineLevel()) {
view->SetHighColor(255, 0, 0);
view->SetDrawingMode(B_OP_COPY);
view->StrokeRect(boundBoxes[i]);
}
// add the bounding to the region.
fBoxRegion.Include(boundBoxes[i]);
xCoord += (escapementArray[i] /*+ escapeDeltas[i].nonspace + escapeDeltas[i].space*/)
* FontSize() + Spacing();
printf("xCoord %f\n", xCoord);
}
}
void
FontDemoView::MessageReceived(BMessage* msg)
{
switch (msg->what) {
case TEXT_CHANGED_MSG:
{
const char* text = NULL;
if (msg->FindString("_text", &text) == B_OK) {
SetString(text);
Invalidate(/*&fBoxRegion*/);
}
break;
}
case FONTSTYLE_CHANGED_MSG:
{
BMessage fontMessage;
if (msg->FindMessage("_fontMessage", &fontMessage) != B_OK)
return;
const char* family;
const char* style;
if (fontMessage.FindString("_family", &family) != B_OK
|| fontMessage.FindString("_style", &style) != B_OK)
return;
fFont.SetFamilyAndStyle(family, style);
Invalidate();
break;
}
case FONTFAMILY_CHANGED_MSG:
{
BMessage fontMessage;
if (msg->FindMessage("_fontMessage", &fontMessage) != B_OK)
return;
const char* family;
if (fontMessage.FindString("_family", &family) != B_OK)
return;
font_style style;
if (get_font_style(const_cast<char*>(family), 0, &style) == B_OK) {
fFont.SetFamilyAndStyle(family, style);
Invalidate(/*&fBoxRegion*/);
}
break;
}
case FONTSIZE_MSG:
{
float size = 0.0;
if (msg->FindFloat("_size", &size) == B_OK) {
SetFontSize(size);
Invalidate(/*&fBoxRegion*/);
}
break;
}
case FONTSHEAR_MSG:
{
float shear = 90.0;
if (msg->FindFloat("_shear", &shear) == B_OK) {
SetFontShear(shear);
Invalidate(/*&fBoxRegion*/);
}
break;
}
case ROTATION_MSG:
{
float rotation = 0.0;
if (msg->FindFloat("_rotation", &rotation) == B_OK) {
SetFontRotation(rotation);
Invalidate(/*&fBoxRegion*/);
}
break;
}
case SPACING_MSG:
{
float space = 0.0;
if (msg->FindFloat("_spacing", &space) == B_OK) {
SetSpacing(space);
Invalidate(/*&fBoxRegion*/);
}
break;
}
case OUTLINE_MSG:
{
int8 outline = 0;
if (msg->FindInt8("_outline", &outline) == B_OK) {
SetOutlineLevel(outline);
Invalidate(/*&fBoxRegion*/);
}
break;
}
case ALIASING_MSG:
{
bool aliased = false;
if (msg->FindBool("_aliased", &aliased) == B_OK) {
SetAntialiasing(aliased);
Invalidate(/*&fBoxRegion*/);
}
break;
}
case BOUNDING_BOX_MSG:
{
bool boundingbox = false;
if (msg->FindBool("_boundingbox", &boundingbox) == B_OK) {
SetDrawBoundingBoxes(boundingbox);
Invalidate(/*&fBoxRegion*/);
}
break;
}
default:
BView::MessageReceived(msg);
break;
}
}
void
FontDemoView::SetString(const char* string)
{
free(fString);
fString = strdup(string);
free(fShapes);
_AddShapes(fString);
}
const char*
FontDemoView::String() const
{
return fString;
}
void
FontDemoView::SetFontSize(float size)
{
fFont.SetSize(size);
}
void
FontDemoView::SetFontShear(float shear)
{
fFont.SetShear(shear);
}
void
FontDemoView::SetFontRotation(float rotation)
{
fFont.SetRotation(rotation);
}
void
FontDemoView::SetDrawBoundingBoxes(bool state)
{
fBoundingBoxes = state;
}
void
FontDemoView::SetAntialiasing(bool state)
{
fFont.SetFlags(state ? B_FORCE_ANTIALIASING : B_DISABLE_ANTIALIASING);
}
void
FontDemoView::SetSpacing(float space)
{
fSpacing = space;
}
void
FontDemoView::SetOutlineLevel(int8 outline)
{
fOutLineLevel = outline;
}
void
FontDemoView::_AddShapes(const char* string)
{
const size_t size = strlen(string);
fShapes = (BShape**)malloc(sizeof(BShape*)*size);
for (size_t i = 0; i < size; i++) {
fShapes[i] = new BShape();
}
}
BView*
FontDemoView::_GetView(BRect rect)
{
if (!fBitmap || fBitmap->Bounds() != rect)
_NewBitmap(rect);
fBitmap->Lock();
return fBitmap->ChildAt(0);
}
void
FontDemoView::_NewBitmap(BRect rect)
{
delete fBitmap;
fBitmap = new BBitmap(rect, B_RGB16, true);
if (fBitmap->Lock()) {
BView* view = new BView(rect, "", B_FOLLOW_NONE, B_WILL_DRAW);
fBitmap->AddChild(view);
fBitmap->Unlock();
} else {
delete fBitmap;
fBitmap = NULL;
}
}

View File

@ -0,0 +1,75 @@
/*
* Copyright 2006, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Mikael Konradson, mikael.konradson@gmail.com
*/
#ifndef FONT_DEMO_VIEW_H
#define FONT_DEMO_VIEW_H
#include <View.h>
#include <Region.h>
class BShape;
class BBitmap;
class FontDemoView : public BView {
public:
FontDemoView(BRect rect);
virtual ~FontDemoView();
virtual void Draw(BRect updateRect);
virtual void MessageReceived(BMessage* message);
virtual void FrameResized(float width, float height);
virtual void SetFontSize(float size);
const float FontSize() const { return fFont.Size(); }
void SetDrawBoundingBoxes(bool state);
bool BoundingBoxes() const { return fBoundingBoxes; }
void SetFontShear(float shear);
const float Shear() const { return fFont.Shear(); }
void SetFontRotation(float rotation);
const float Rotation() const { return fFont.Rotation(); }
void SetString(const char* string);
const char* String() const;
void SetAntialiasing(bool state);
void SetSpacing(float space);
const float Spacing() const { return fSpacing; }
void SetOutlineLevel(int8 outline);
const int8 OutLineLevel() const { return fOutLineLevel; }
private:
void _AddShapes(const char* string);
void _DrawView(BView* view);
BView* _GetView(BRect rect);
void _NewBitmap(BRect rect);
BBitmap* fBitmap;
BView* fBufferView;
char* fString;
float fFontSize;
float fSpacing;
int8 fOutLineLevel;
BRegion fBoxRegion;
BFont fFont;
bool fBoundingBoxes;
bool fDrawShapes;
BShape** fShapes;
};
#endif // FONT_DEMO_VIEW_H

11
src/apps/fontdemo/Jamfile Normal file
View File

@ -0,0 +1,11 @@
SubDir HAIKU_TOP src apps fontdemo ;
SetSubDirSupportedPlatformsBeOSCompatible ;
Application FontDemo :
ControlView.cpp
FontDemo.cpp
FontDemoView.cpp
: be
: FontDemo.rdef
;

View File

@ -0,0 +1,24 @@
/*
* Copyright 2006, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Mikael Konradson, mikael.konradson@gmail.com
*/
#ifndef MESSAGES_H
#define MESSAGES_H
const uint32 FONTSIZE_MSG = 'size';
const uint32 FONTSHEAR_MSG = 'shea';
const uint32 ROTATION_MSG = 'rota';
const uint32 SPACING_MSG = 'spac';
const uint32 OUTLINE_MSG = 'outl';
const uint32 ALIASING_MSG = 'alia';
const uint32 BOUNDING_BOX_MSG = 'bond';
const uint32 CYCLING_FONTS_MSG = 'cycl';
const uint32 CYCLING_FONTS_UPDATE_MSG = 'cycU';
const uint32 FONTSTYLE_CHANGED_MSG = 'fonS';
const uint32 FONTFAMILY_CHANGED_MSG = 'fonF';
const uint32 TEXT_CHANGED_MSG = 'text';
#endif // MESSAGES_H