2 * Copyright 2006-2009, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
6 * Mikael Konradson, mikael.konradson@gmail.com
10 #include "FontDemoView.h"
23 #include <StackOrHeapArray.h>
27 #undef B_TRANSLATION_CONTEXT
28 #define B_TRANSLATION_CONTEXT "FontDemoView"
30 FontDemoView::FontDemoView(BRect rect
)
31 : BView(rect
, "FontDemoView", B_FOLLOW_ALL
, B_WILL_DRAW
| B_FRAME_EVENTS
),
37 fDrawingMode(B_OP_COPY
),
38 fBoundingBoxes(false),
42 SetViewColor(B_TRANSPARENT_COLOR
);
43 BString setStr
= B_TRANSLATE("Haiku, Inc.");
45 SetFontSize(fFontSize
);
46 SetAntialiasing(true);
52 FontDemoView::~FontDemoView()
62 FontDemoView::FrameResized(float width
, float height
)
64 // TODO: We shouldnt invalidate the whole view when bounding boxes are
66 Invalidate(/*fBoxRegion.Frame()*/);
67 BView::FrameResized(width
, height
);
72 FontDemoView::Draw(BRect updateRect
)
74 BRect rect
= Bounds();
75 fBufferView
= _GetView(rect
);
76 _DrawView(fBufferView
);
79 DrawBitmap(fBitmap
, rect
);
85 FontDemoView::_DrawView(BView
* view
)
90 view
->SetDrawingMode(B_OP_COPY
);
93 BRect rect
= view
->Bounds();
94 view
->SetHighColor(255, 255, 255);
100 view
->SetFont(&fFont
, B_FONT_ALL
);
102 const size_t size
= fString
.CountChars();
103 BStackOrHeapArray
<BRect
, 64> boundBoxes(size
);
106 fFont
.GetGlyphShapes(fString
, size
, fShapes
);
108 fFont
.GetBoundingBoxesAsGlyphs(fString
, size
, B_SCREEN_METRIC
, boundBoxes
);
110 float escapementArray
[size
];
111 //struct escapement_delta escapeDeltas[size];
112 struct edge_info edgeInfo
[size
];
114 for (size_t j = 0; j < size; j++) {
115 escapeDeltas[j].nonspace = 0.0f;
116 escapeDeltas[j].space = 0.0f;
119 fFont
.GetEdges(fString
.String(), size
, edgeInfo
);
120 fFont
.GetEscapements(fString
.String(), size
, /*escapeDeltas,*/ escapementArray
);
123 fFont
.GetHeight(&fh
);
125 float xCoordArray
[size
];
126 float yCoordArray
[size
];
128 float yCoord
= (rect
.Height() + fh
.ascent
- fh
.descent
) / 2;
129 float xCoord
= -rect
.Width() / 2;
130 const float xCenter
= xCoord
* -1;
131 const float r
= Rotation() * (M_PI
/ 180.0);
132 const float cosinus
= cos(r
);
133 const float sinus
= -sin(r
);
135 // When the bounding boxes workes properly we will invalidate only the
136 // region area instead of the whole view.
138 fBoxRegion
.MakeEmpty();
140 for (size_t i
= 0; i
< size
; i
++) {
141 xCoordArray
[i
] = 0.0f
;
142 yCoordArray
[i
] = 0.0f
;
144 yCoordArray
[i
] = sinus
* (xCoord
- xCoordArray
[i
]);
145 xCoordArray
[i
] = cosinus
* xCoord
;
147 xCoordArray
[i
] += xCenter
;
148 yCoordArray
[i
] += yCoord
;
150 boundBoxes
[i
].OffsetBy(xCoordArray
[i
], yCoordArray
[i
]);
152 if (OutLineLevel()) {
153 view
->MovePenTo(xCoordArray
[i
], yCoordArray
[i
]);
154 view
->SetHighColor(ui_color(B_PANEL_BACKGROUND_COLOR
));
155 view
->FillShape(fShapes
[i
]);
156 view
->SetPenSize(OutLineLevel());
157 view
->SetHighColor(0, 0, 0);
158 view
->StrokeShape(fShapes
[i
]);
160 view
->SetHighColor(0, 0, 0);
161 view
->SetDrawingMode(fDrawingMode
);
163 const char* charAt
= fString
.CharAt(i
, &charLength
);
164 view
->DrawString(charAt
, charLength
,
165 BPoint(xCoordArray
[i
], yCoordArray
[i
]));
168 if (BoundingBoxes() && !OutLineLevel()) {
170 view
->SetHighColor(0, 255, 0);
172 view
->SetHighColor(255, 0, 0);
173 view
->SetDrawingMode(B_OP_COPY
);
174 view
->StrokeRect(boundBoxes
[i
]);
177 // add the bounding to the region.
178 fBoxRegion
.Include(boundBoxes
[i
]);
180 xCoord
+= (escapementArray
[i
] /*+ escapeDeltas[i].nonspace + escapeDeltas[i].space*/)
181 * FontSize() + Spacing();
182 //printf("xCoord %f\n", xCoord);
188 FontDemoView::MessageReceived(BMessage
* msg
)
191 case TEXT_CHANGED_MSG
:
194 if (msg
->FindString("_text", &text
) == B_OK
) {
196 Invalidate(/*&fBoxRegion*/);
201 case FONTSTYLE_CHANGED_MSG
:
203 BMessage fontMessage
;
204 if (msg
->FindMessage("_fontMessage", &fontMessage
) != B_OK
)
209 if (fontMessage
.FindString("_family", &family
) != B_OK
210 || fontMessage
.FindString("_style", &style
) != B_OK
)
213 fFont
.SetFamilyAndStyle(family
, style
);
218 case FONTFAMILY_CHANGED_MSG
:
220 BMessage fontMessage
;
221 if (msg
->FindMessage("_fontMessage", &fontMessage
) != B_OK
)
225 if (fontMessage
.FindString("_family", &family
) != B_OK
)
229 if (get_font_style(const_cast<char*>(family
), 0, &style
) == B_OK
) {
230 fFont
.SetFamilyAndStyle(family
, style
);
231 Invalidate(/*&fBoxRegion*/);
239 if (msg
->FindFloat("_size", &size
) == B_OK
) {
241 Invalidate(/*&fBoxRegion*/);
249 if (msg
->FindFloat("_shear", &shear
) == B_OK
) {
251 Invalidate(/*&fBoxRegion*/);
258 float rotation
= 0.0;
259 if (msg
->FindFloat("_rotation", &rotation
) == B_OK
) {
260 SetFontRotation(rotation
);
261 Invalidate(/*&fBoxRegion*/);
269 if (msg
->FindFloat("_spacing", &space
) == B_OK
) {
271 Invalidate(/*&fBoxRegion*/);
279 if (msg
->FindInt8("_outline", &outline
) == B_OK
) {
280 SetOutlineLevel(outline
);
281 Invalidate(/*&fBoxRegion*/);
288 bool aliased
= false;
289 if (msg
->FindBool("_aliased", &aliased
) == B_OK
) {
290 SetAntialiasing(aliased
);
291 Invalidate(/*&fBoxRegion*/);
296 case DRAWINGMODE_CHANGED_MSG
:
298 if (msg
->FindInt32("_mode", (int32
*)&fDrawingMode
) == B_OK
) {
299 Invalidate(/*&fBoxRegion*/);
300 switch (fDrawingMode
) {
302 printf("Drawing mode: B_OP_COPY\n");
305 printf("Drawing mode: B_OP_OVER\n");
308 printf("Drawing mode: B_OP_ERASE\n");
311 printf("Drawing mode: B_OP_INVERT\n");
314 printf("Drawing mode: B_OP_ADD\n");
317 printf("Drawing mode: B_OP_SUBTRACT\n");
320 printf("Drawing mode: B_OP_BLEND\n");
323 printf("Drawing mode: B_OP_MIN\n");
326 printf("Drawing mode: B_OP_MAX\n");
329 printf("Drawing mode: B_OP_SELECT\n");
332 printf("Drawing mode: B_OP_ALPHA\n");
335 printf("Drawing mode: %d\n", fDrawingMode
);
341 case BOUNDING_BOX_MSG
:
343 bool boundingbox
= false;
344 if (msg
->FindBool("_boundingbox", &boundingbox
) == B_OK
) {
345 SetDrawBoundingBoxes(boundingbox
);
346 Invalidate(/*&fBoxRegion*/);
352 BView::MessageReceived(msg
);
359 FontDemoView::SetString(BString string
)
368 FontDemoView::String() const
375 FontDemoView::SetFontSize(float size
)
382 FontDemoView::SetFontShear(float shear
)
384 fFont
.SetShear(shear
);
389 FontDemoView::SetFontRotation(float rotation
)
391 fFont
.SetRotation(rotation
);
396 FontDemoView::SetDrawBoundingBoxes(bool state
)
398 fBoundingBoxes
= state
;
403 FontDemoView::SetAntialiasing(bool state
)
405 fFont
.SetFlags(state
? B_FORCE_ANTIALIASING
: B_DISABLE_ANTIALIASING
);
410 FontDemoView::SetSpacing(float space
)
417 FontDemoView::SetOutlineLevel(int8 outline
)
419 fOutLineLevel
= outline
;
424 FontDemoView::_AddShapes(BString string
)
426 const size_t size
= string
.CountChars();
427 fShapes
= (BShape
**)malloc(sizeof(BShape
*) * size
);
429 for (size_t i
= 0; i
< size
; i
++) {
430 fShapes
[i
] = new BShape();
436 FontDemoView::_GetView(BRect rect
)
438 if (!fBitmap
|| fBitmap
->Bounds() != rect
)
442 return fBitmap
->ChildAt(0);
447 FontDemoView::_NewBitmap(BRect rect
)
450 fBitmap
= new BBitmap(rect
, B_RGB16
, true);
452 if (fBitmap
->Lock()) {
453 BView
* view
= new BView(rect
, "", B_FOLLOW_NONE
, B_WILL_DRAW
);
454 fBitmap
->AddChild(view
);