From b7652959706ec2bd94c4a5586945e05df6dab4d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Tue, 6 Jun 2006 19:40:16 +0000 Subject: [PATCH] Added a FontDemo replacement, contributed by Mikael Konradson. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@17745 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/apps/Jamfile | 1 + src/apps/fontdemo/ControlView.cpp | 498 +++++++++++++++++++++++++++++ src/apps/fontdemo/ControlView.h | 63 ++++ src/apps/fontdemo/FontDemo.cpp | 62 ++++ src/apps/fontdemo/FontDemo.h | 23 ++ src/apps/fontdemo/FontDemo.rdef | 76 +++++ src/apps/fontdemo/FontDemoView.cpp | 405 +++++++++++++++++++++++ src/apps/fontdemo/FontDemoView.h | 75 +++++ src/apps/fontdemo/Jamfile | 11 + src/apps/fontdemo/messages.h | 24 ++ 10 files changed, 1238 insertions(+) create mode 100644 src/apps/fontdemo/ControlView.cpp create mode 100644 src/apps/fontdemo/ControlView.h create mode 100644 src/apps/fontdemo/FontDemo.cpp create mode 100644 src/apps/fontdemo/FontDemo.h create mode 100644 src/apps/fontdemo/FontDemo.rdef create mode 100644 src/apps/fontdemo/FontDemoView.cpp create mode 100644 src/apps/fontdemo/FontDemoView.h create mode 100644 src/apps/fontdemo/Jamfile create mode 100644 src/apps/fontdemo/messages.h diff --git a/src/apps/Jamfile b/src/apps/Jamfile index daf19fadc0..7077f131c7 100644 --- a/src/apps/Jamfile +++ b/src/apps/Jamfile @@ -11,6 +11,7 @@ SubInclude HAIKU_TOP src apps deskbar ; SubInclude HAIKU_TOP src apps deskcalc ; SubInclude HAIKU_TOP src apps diskprobe ; SubInclude HAIKU_TOP src apps expander ; +SubInclude HAIKU_TOP src apps fontdemo ; SubInclude HAIKU_TOP src apps glteapot ; SubInclude HAIKU_TOP src apps installer ; SubInclude HAIKU_TOP src apps magnify ; diff --git a/src/apps/fontdemo/ControlView.cpp b/src/apps/fontdemo/ControlView.cpp new file mode 100644 index 0000000000..6096304883 --- /dev/null +++ b/src/apps/fontdemo/ControlView.cpp @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +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(fFontsizeSlider->Value())); + fFontsizeSlider->SetLabel(buff); + + BMessage msg(FONTSIZE_MSG); + msg.AddFloat("_size", static_cast(fFontsizeSlider->Value())); + fMessenger->SendMessage(&msg); + break; + } + + case FONTSHEAR_MSG: + { + char buff[256]; + sprintf(buff, "Shear: %d", static_cast(fShearSlider->Value())); + fShearSlider->SetLabel(buff); + + BMessage msg(FONTSHEAR_MSG); + msg.AddFloat("_shear", static_cast(fShearSlider->Value())); + fMessenger->SendMessage(&msg); + break; + } + + case ROTATION_MSG: + { + char buff[256]; + sprintf(buff, "Rotation: %d", static_cast(fRotationSlider->Value())); + fRotationSlider->SetLabel(buff); + + BMessage msg(ROTATION_MSG); + msg.AddFloat("_rotation", static_cast(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(fSpacingSlider->Value())); + fMessenger->SendMessage(&msg); + break; + } + + case ALIASING_MSG: + { + BMessage msg(ALIASING_MSG); + msg.AddBool("_aliased", static_cast(fAliasingCheckBox->Value())); + fMessenger->SendMessage(&msg); + break; + } + + case BOUNDING_BOX_MSG: + { + BMessage msg(BOUNDING_BOX_MSG); + msg.AddBool("_boundingbox", static_cast(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(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(¤tFamily, ¤tStyle); + + 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); + } + } +} + diff --git a/src/apps/fontdemo/ControlView.h b/src/apps/fontdemo/ControlView.h new file mode 100644 index 0000000000..aac22622b4 --- /dev/null +++ b/src/apps/fontdemo/ControlView.h @@ -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 + + +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 + diff --git a/src/apps/fontdemo/FontDemo.cpp b/src/apps/fontdemo/FontDemo.cpp new file mode 100644 index 0000000000..1d3558bb95 --- /dev/null +++ b/src/apps/fontdemo/FontDemo.cpp @@ -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 + + +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; +} + diff --git a/src/apps/fontdemo/FontDemo.h b/src/apps/fontdemo/FontDemo.h new file mode 100644 index 0000000000..b7aac3f9f5 --- /dev/null +++ b/src/apps/fontdemo/FontDemo.h @@ -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 + + +class FontDemo : public BApplication { + public: + FontDemo(); + virtual ~FontDemo(); + + virtual void ReadyToRun(); +}; + +#endif // FONT_DEMO_H diff --git a/src/apps/fontdemo/FontDemo.rdef b/src/apps/fontdemo/FontDemo.rdef new file mode 100644 index 0000000000..88e5177926 --- /dev/null +++ b/src/apps/fontdemo/FontDemo.rdef @@ -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" +}; diff --git a/src/apps/fontdemo/FontDemoView.cpp b/src/apps/fontdemo/FontDemoView.cpp new file mode 100644 index 0000000000..f88bfdf453 --- /dev/null +++ b/src/apps/fontdemo/FontDemoView.cpp @@ -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 +#include +#include +#include + +#include +#include +#include +#include + + +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(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; + } +} + diff --git a/src/apps/fontdemo/FontDemoView.h b/src/apps/fontdemo/FontDemoView.h new file mode 100644 index 0000000000..652c372e17 --- /dev/null +++ b/src/apps/fontdemo/FontDemoView.h @@ -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 +#include + +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 + + diff --git a/src/apps/fontdemo/Jamfile b/src/apps/fontdemo/Jamfile new file mode 100644 index 0000000000..b68b767010 --- /dev/null +++ b/src/apps/fontdemo/Jamfile @@ -0,0 +1,11 @@ +SubDir HAIKU_TOP src apps fontdemo ; + +SetSubDirSupportedPlatformsBeOSCompatible ; + +Application FontDemo : + ControlView.cpp + FontDemo.cpp + FontDemoView.cpp + : be + : FontDemo.rdef + ; diff --git a/src/apps/fontdemo/messages.h b/src/apps/fontdemo/messages.h new file mode 100644 index 0000000000..91eac3034b --- /dev/null +++ b/src/apps/fontdemo/messages.h @@ -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