btrfs: Attempt to fix GCC2 build.
[haiku.git] / src / apps / fontdemo / FontDemoView.cpp
blobec1ab5498fa130421b648d7e4eee5870d84fe922
1 /*
2 * Copyright 2006-2009, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Mikael Konradson, mikael.konradson@gmail.com
7 */
10 #include "FontDemoView.h"
12 #include <math.h>
13 #include <stdlib.h>
14 #include <stdio.h>
15 #include <string.h>
17 #include <Catalog.h>
18 #include <Bitmap.h>
19 #include <Font.h>
20 #include <Message.h>
21 #include <Shape.h>
22 #include <String.h>
23 #include <StackOrHeapArray.h>
25 #include "messages.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),
32 fBitmap(NULL),
33 fBufferView(NULL),
34 fFontSize(50.0),
35 fSpacing(0.0),
36 fOutLineLevel(0),
37 fDrawingMode(B_OP_COPY),
38 fBoundingBoxes(false),
39 fDrawShapes(false),
40 fShapes(NULL)
42 SetViewColor(B_TRANSPARENT_COLOR);
43 BString setStr = B_TRANSLATE("Haiku, Inc.");
44 SetString(setStr);
45 SetFontSize(fFontSize);
46 SetAntialiasing(true);
48 _NewBitmap(Bounds());
52 FontDemoView::~FontDemoView()
54 free(fShapes);
56 fBitmap->Lock();
57 delete fBitmap;
61 void
62 FontDemoView::FrameResized(float width, float height)
64 // TODO: We shouldnt invalidate the whole view when bounding boxes are
65 // working as wanted
66 Invalidate(/*fBoxRegion.Frame()*/);
67 BView::FrameResized(width, height);
71 void
72 FontDemoView::Draw(BRect updateRect)
74 BRect rect = Bounds();
75 fBufferView = _GetView(rect);
76 _DrawView(fBufferView);
78 fBufferView->Sync();
79 DrawBitmap(fBitmap, rect);
80 fBitmap->Unlock();
84 void
85 FontDemoView::_DrawView(BView* view)
87 if (!view)
88 return;
90 view->SetDrawingMode(B_OP_COPY);
93 BRect rect = view->Bounds();
94 view->SetHighColor(255, 255, 255);
95 view->FillRect(rect);
97 if (!fString)
98 return;
100 view->SetFont(&fFont, B_FONT_ALL);
102 const size_t size = fString.CountChars();
103 BStackOrHeapArray<BRect, 64> boundBoxes(size);
105 if (OutLineLevel())
106 fFont.GetGlyphShapes(fString, size, fShapes);
107 else
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);
122 font_height fh;
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]);
159 } else {
160 view->SetHighColor(0, 0, 0);
161 view->SetDrawingMode(fDrawingMode);
162 int32 charLength;
163 const char* charAt = fString.CharAt(i, &charLength);
164 view->DrawString(charAt, charLength,
165 BPoint(xCoordArray[i], yCoordArray[i]));
168 if (BoundingBoxes() && !OutLineLevel()) {
169 if (i % 2)
170 view->SetHighColor(0, 255, 0);
171 else
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);
187 void
188 FontDemoView::MessageReceived(BMessage* msg)
190 switch (msg->what) {
191 case TEXT_CHANGED_MSG:
193 BString text;
194 if (msg->FindString("_text", &text) == B_OK) {
195 SetString(text);
196 Invalidate(/*&fBoxRegion*/);
198 break;
201 case FONTSTYLE_CHANGED_MSG:
203 BMessage fontMessage;
204 if (msg->FindMessage("_fontMessage", &fontMessage) != B_OK)
205 return;
207 const char* family;
208 const char* style;
209 if (fontMessage.FindString("_family", &family) != B_OK
210 || fontMessage.FindString("_style", &style) != B_OK)
211 return;
213 fFont.SetFamilyAndStyle(family, style);
214 Invalidate();
215 break;
218 case FONTFAMILY_CHANGED_MSG:
220 BMessage fontMessage;
221 if (msg->FindMessage("_fontMessage", &fontMessage) != B_OK)
222 return;
224 const char* family;
225 if (fontMessage.FindString("_family", &family) != B_OK)
226 return;
228 font_style style;
229 if (get_font_style(const_cast<char*>(family), 0, &style) == B_OK) {
230 fFont.SetFamilyAndStyle(family, style);
231 Invalidate(/*&fBoxRegion*/);
233 break;
236 case FONTSIZE_MSG:
238 float size = 0.0;
239 if (msg->FindFloat("_size", &size) == B_OK) {
240 SetFontSize(size);
241 Invalidate(/*&fBoxRegion*/);
243 break;
246 case FONTSHEAR_MSG:
248 float shear = 90.0;
249 if (msg->FindFloat("_shear", &shear) == B_OK) {
250 SetFontShear(shear);
251 Invalidate(/*&fBoxRegion*/);
253 break;
256 case ROTATION_MSG:
258 float rotation = 0.0;
259 if (msg->FindFloat("_rotation", &rotation) == B_OK) {
260 SetFontRotation(rotation);
261 Invalidate(/*&fBoxRegion*/);
263 break;
266 case SPACING_MSG:
268 float space = 0.0;
269 if (msg->FindFloat("_spacing", &space) == B_OK) {
270 SetSpacing(space);
271 Invalidate(/*&fBoxRegion*/);
273 break;
276 case OUTLINE_MSG:
278 int8 outline = 0;
279 if (msg->FindInt8("_outline", &outline) == B_OK) {
280 SetOutlineLevel(outline);
281 Invalidate(/*&fBoxRegion*/);
283 break;
286 case ALIASING_MSG:
288 bool aliased = false;
289 if (msg->FindBool("_aliased", &aliased) == B_OK) {
290 SetAntialiasing(aliased);
291 Invalidate(/*&fBoxRegion*/);
293 break;
296 case DRAWINGMODE_CHANGED_MSG:
298 if (msg->FindInt32("_mode", (int32 *)&fDrawingMode) == B_OK) {
299 Invalidate(/*&fBoxRegion*/);
300 switch (fDrawingMode) {
301 case B_OP_COPY:
302 printf("Drawing mode: B_OP_COPY\n");
303 break;
304 case B_OP_OVER:
305 printf("Drawing mode: B_OP_OVER\n");
306 break;
307 case B_OP_ERASE:
308 printf("Drawing mode: B_OP_ERASE\n");
309 break;
310 case B_OP_INVERT:
311 printf("Drawing mode: B_OP_INVERT\n");
312 break;
313 case B_OP_ADD:
314 printf("Drawing mode: B_OP_ADD\n");
315 break;
316 case B_OP_SUBTRACT:
317 printf("Drawing mode: B_OP_SUBTRACT\n");
318 break;
319 case B_OP_BLEND:
320 printf("Drawing mode: B_OP_BLEND\n");
321 break;
322 case B_OP_MIN:
323 printf("Drawing mode: B_OP_MIN\n");
324 break;
325 case B_OP_MAX:
326 printf("Drawing mode: B_OP_MAX\n");
327 break;
328 case B_OP_SELECT:
329 printf("Drawing mode: B_OP_SELECT\n");
330 break;
331 case B_OP_ALPHA:
332 printf("Drawing mode: B_OP_ALPHA\n");
333 break;
334 default:
335 printf("Drawing mode: %d\n", fDrawingMode);
338 break;
341 case BOUNDING_BOX_MSG:
343 bool boundingbox = false;
344 if (msg->FindBool("_boundingbox", &boundingbox) == B_OK) {
345 SetDrawBoundingBoxes(boundingbox);
346 Invalidate(/*&fBoxRegion*/);
348 break;
351 default:
352 BView::MessageReceived(msg);
353 break;
358 void
359 FontDemoView::SetString(BString string)
361 fString = string;
362 free(fShapes);
363 _AddShapes(fString);
367 BString
368 FontDemoView::String() const
370 return fString;
374 void
375 FontDemoView::SetFontSize(float size)
377 fFont.SetSize(size);
381 void
382 FontDemoView::SetFontShear(float shear)
384 fFont.SetShear(shear);
388 void
389 FontDemoView::SetFontRotation(float rotation)
391 fFont.SetRotation(rotation);
395 void
396 FontDemoView::SetDrawBoundingBoxes(bool state)
398 fBoundingBoxes = state;
402 void
403 FontDemoView::SetAntialiasing(bool state)
405 fFont.SetFlags(state ? B_FORCE_ANTIALIASING : B_DISABLE_ANTIALIASING);
409 void
410 FontDemoView::SetSpacing(float space)
412 fSpacing = space;
416 void
417 FontDemoView::SetOutlineLevel(int8 outline)
419 fOutLineLevel = outline;
423 void
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();
435 BView*
436 FontDemoView::_GetView(BRect rect)
438 if (!fBitmap || fBitmap->Bounds() != rect)
439 _NewBitmap(rect);
441 fBitmap->Lock();
442 return fBitmap->ChildAt(0);
446 void
447 FontDemoView::_NewBitmap(BRect rect)
449 delete fBitmap;
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);
455 fBitmap->Unlock();
456 } else {
457 delete fBitmap;
458 fBitmap = NULL;