1 /*
2 * Copyright 2008, Stephan Aßmus, <superstippi@gmx.de>
3 * Copyright 2008, Andrej Spielmann, <andrej.spielmann@seh.ox.ac.uk>
4 * All rights reserved. Distributed under the terms of the MIT License.
5 */
6
7
8 #include "AntialiasingSettingsView.h"
9
10 #include <stdio.h>
11 #include <stdlib.h>
12
13 #include <Box.h>
14 #include <Catalog.h>
15 #include <LayoutBuilder.h>
16 #include <Locale.h>
17 #include <MenuField.h>
18 #include <MenuItem.h>
19 #include <PopUpMenu.h>
20 #include <Slider.h>
21 #include <SpaceLayoutItem.h>
22 #include <String.h>
23 #include <TextView.h>
24
25
26 #include "APRWindow.h"
27
28 #undef B_TRANSLATION_CONTEXT
29 #define B_TRANSLATION_CONTEXT "AntialiasingSettingsView"
30
31
32 static const int32 kMsgSetAntialiasing = 'anti';
33 static const int32 kMsgSetHinting = 'hint';
34 static const int32 kMsgSetAverageWeight = 'avrg';
35 static const char* kSubpixelLabel = B_TRANSLATE_MARK("LCD subpixel");
36 static const char* kGrayscaleLabel = B_TRANSLATE_MARK("Grayscale");
37 static const char* kNoHintingLabel = B_TRANSLATE_MARK("Off");
38 static const char* kMonospacedHintingLabel =
39 B_TRANSLATE_MARK("Monospaced fonts only");
40 static const char* kFullHintingLabel = B_TRANSLATE_MARK("On");
41
42
43 // #pragma mark - private libbe API
44
45
46 enum {
47 HINTING_MODE_OFF = 0,
48 HINTING_MODE_ON,
49 HINTING_MODE_MONOSPACED_ONLY
50 };
51
52 static const uint8 kDefaultHintingMode = HINTING_MODE_ON;
53 static const unsigned char kDefaultAverageWeight = 120;
54 static const bool kDefaultSubpixelAntialiasing = true;
55
56 extern void set_subpixel_antialiasing(bool subpix);
57 extern status_t get_subpixel_antialiasing(bool* subpix);
58 extern void set_hinting_mode(uint8 hinting);
59 extern status_t get_hinting_mode(uint8* hinting);
60 extern void set_average_weight(unsigned char averageWeight);
61 extern status_t get_average_weight(unsigned char* averageWeight);
62
63
64 // #pragma mark -
65
66
AntialiasingSettingsView(const char * name)67 AntialiasingSettingsView::AntialiasingSettingsView(const char* name)
68 : BView(name, 0)
69 {
70 // collect the current system settings
71 if (get_subpixel_antialiasing(&fCurrentSubpixelAntialiasing) != B_OK)
72 fCurrentSubpixelAntialiasing = kDefaultSubpixelAntialiasing;
73 fSavedSubpixelAntialiasing = fCurrentSubpixelAntialiasing;
74
75 if (get_hinting_mode(&fCurrentHinting) != B_OK)
76 fCurrentHinting = kDefaultHintingMode;
77 fSavedHinting = fCurrentHinting;
78
79 if (get_average_weight(&fCurrentAverageWeight) != B_OK)
80 fCurrentAverageWeight = kDefaultAverageWeight;
81 fSavedAverageWeight = fCurrentAverageWeight;
82
83 // create the controls
84
85 // antialiasing menu
86 _BuildAntialiasingMenu();
87 fAntialiasingMenuField = new BMenuField("antialiasing",
88 B_TRANSLATE("Antialiasing type:"), fAntialiasingMenu);
89
90 // "average weight" in subpixel filtering
91 fAverageWeightControl = new BSlider("averageWeightControl",
92 B_TRANSLATE("Reduce colored edges filter strength:"),
93 new BMessage(kMsgSetAverageWeight), 0, 255, B_HORIZONTAL);
94 fAverageWeightControl->SetLimitLabels(B_TRANSLATE("Off"),
95 B_TRANSLATE("Strong"));
96 fAverageWeightControl->SetHashMarks(B_HASH_MARKS_BOTTOM);
97 fAverageWeightControl->SetHashMarkCount(255 / 15);
98 fAverageWeightControl->SetEnabled(false);
99
100 // hinting menu
101 _BuildHintingMenu();
102 fHintingMenuField = new BMenuField("hinting", B_TRANSLATE("Glyph hinting:"),
103 fHintingMenu);
104
105 BLayoutBuilder::Grid<>(this, B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING)
106 // controls pane
107 .AddMenuField(fHintingMenuField, 0, 0)
108 .AddMenuField(fAntialiasingMenuField, 0, 1)
109 .Add(fAverageWeightControl, 0, 2, 3)
110
111 .AddGlue(0, 3)
112 .SetInsets(B_USE_WINDOW_SPACING);
113
114 BGridLayout* layout = dynamic_cast<BGridLayout*>(GetLayout());
115 layout->SetMinColumnWidth(0,
116 StringWidth(B_TRANSLATE("Antialiasing type:")) * 2);
117
118 _SetCurrentAntialiasing();
119 _SetCurrentHinting();
120 _SetCurrentAverageWeight();
121 }
122
123
~AntialiasingSettingsView()124 AntialiasingSettingsView::~AntialiasingSettingsView()
125 {
126 }
127
128
129 void
AttachedToWindow()130 AntialiasingSettingsView::AttachedToWindow()
131 {
132 AdoptParentColors();
133
134 if (Parent() == NULL)
135 SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
136
137 fAntialiasingMenu->SetTargetForItems(this);
138 fHintingMenu->SetTargetForItems(this);
139 fAverageWeightControl->SetTarget(this);
140 }
141
142
143 void
MessageReceived(BMessage * msg)144 AntialiasingSettingsView::MessageReceived(BMessage *msg)
145 {
146 switch (msg->what) {
147 case kMsgSetAntialiasing:
148 {
149 bool subpixelAntialiasing;
150 if (msg->FindBool("antialiasing", &subpixelAntialiasing) != B_OK
151 || subpixelAntialiasing == fCurrentSubpixelAntialiasing)
152 break;
153
154 fCurrentSubpixelAntialiasing = subpixelAntialiasing;
155 fAverageWeightControl->SetEnabled(fCurrentSubpixelAntialiasing);
156
157 set_subpixel_antialiasing(fCurrentSubpixelAntialiasing);
158
159 Window()->PostMessage(kMsgUpdate);
160 break;
161 }
162 case kMsgSetHinting:
163 {
164 int8 hinting;
165 if (msg->FindInt8("hinting", &hinting) != B_OK
166 || hinting == fCurrentHinting)
167 break;
168
169 fCurrentHinting = hinting;
170 set_hinting_mode(fCurrentHinting);
171
172 Window()->PostMessage(kMsgUpdate);
173 break;
174 }
175 case kMsgSetAverageWeight:
176 {
177 int32 averageWeight = fAverageWeightControl->Value();
178 if (averageWeight == fCurrentAverageWeight)
179 break;
180
181 fCurrentAverageWeight = averageWeight;
182
183 set_average_weight(fCurrentAverageWeight);
184
185 Window()->PostMessage(kMsgUpdate);
186 break;
187 }
188 default:
189 BView::MessageReceived(msg);
190 }
191 }
192
193
194 void
_BuildAntialiasingMenu()195 AntialiasingSettingsView::_BuildAntialiasingMenu()
196 {
197 fAntialiasingMenu = new BPopUpMenu(B_TRANSLATE("Antialiasing menu"));
198
199 BMessage* message = new BMessage(kMsgSetAntialiasing);
200 message->AddBool("antialiasing", false);
201
202 BMenuItem* item
203 = new BMenuItem(B_TRANSLATE_NOCOLLECT(kGrayscaleLabel), message);
204
205 fAntialiasingMenu->AddItem(item);
206
207 message = new BMessage(kMsgSetAntialiasing);
208 message->AddBool("antialiasing", true);
209
210 item = new BMenuItem(B_TRANSLATE_NOCOLLECT(kSubpixelLabel), message);
211
212 fAntialiasingMenu->AddItem(item);
213 }
214
215
216 void
_BuildHintingMenu()217 AntialiasingSettingsView::_BuildHintingMenu()
218 {
219 fHintingMenu = new BPopUpMenu(B_TRANSLATE("Hinting menu"));
220
221 BMessage* message = new BMessage(kMsgSetHinting);
222 message->AddInt8("hinting", HINTING_MODE_OFF);
223 fHintingMenu->AddItem(new BMenuItem(B_TRANSLATE_NOCOLLECT(kNoHintingLabel),
224 message));
225
226 message = new BMessage(kMsgSetHinting);
227 message->AddInt8("hinting", HINTING_MODE_ON);
228 fHintingMenu->AddItem(new BMenuItem(
229 B_TRANSLATE_NOCOLLECT(kFullHintingLabel), message));
230
231 message = new BMessage(kMsgSetHinting);
232 message->AddInt8("hinting", HINTING_MODE_MONOSPACED_ONLY);
233 fHintingMenu->AddItem(new BMenuItem(
234 B_TRANSLATE_NOCOLLECT(kMonospacedHintingLabel), message));
235 }
236
237
238 void
_SetCurrentAntialiasing()239 AntialiasingSettingsView::_SetCurrentAntialiasing()
240 {
241 BMenuItem *item = fAntialiasingMenu->FindItem(
242 fCurrentSubpixelAntialiasing
243 ? B_TRANSLATE_NOCOLLECT(kSubpixelLabel)
244 : B_TRANSLATE_NOCOLLECT(kGrayscaleLabel));
245 if (item != NULL)
246 item->SetMarked(true);
247 if (fCurrentSubpixelAntialiasing)
248 fAverageWeightControl->SetEnabled(true);
249 }
250
251
252 void
_SetCurrentHinting()253 AntialiasingSettingsView::_SetCurrentHinting()
254 {
255 const char* label;
256 switch (fCurrentHinting) {
257 case HINTING_MODE_OFF:
258 label = kNoHintingLabel;
259 break;
260 case HINTING_MODE_ON:
261 label = kFullHintingLabel;
262 break;
263 case HINTING_MODE_MONOSPACED_ONLY:
264 label = kMonospacedHintingLabel;
265 break;
266 default:
267 return;
268 }
269
270 BMenuItem *item = fHintingMenu->FindItem(B_TRANSLATE_NOCOLLECT(label));
271 if (item != NULL)
272 item->SetMarked(true);
273 }
274
275
276 void
_SetCurrentAverageWeight()277 AntialiasingSettingsView::_SetCurrentAverageWeight()
278 {
279 fAverageWeightControl->SetValue(fCurrentAverageWeight);
280 }
281
282
283 void
SetDefaults()284 AntialiasingSettingsView::SetDefaults()
285 {
286 if (!IsDefaultable())
287 return;
288
289 fCurrentSubpixelAntialiasing = kDefaultSubpixelAntialiasing;
290 fCurrentHinting = kDefaultHintingMode;
291 fCurrentAverageWeight = kDefaultAverageWeight;
292
293 set_subpixel_antialiasing(fCurrentSubpixelAntialiasing);
294 set_hinting_mode(fCurrentHinting);
295 set_average_weight(fCurrentAverageWeight);
296
297 _SetCurrentAntialiasing();
298 _SetCurrentHinting();
299 _SetCurrentAverageWeight();
300 }
301
302
303 bool
IsDefaultable()304 AntialiasingSettingsView::IsDefaultable()
305 {
306 return fCurrentSubpixelAntialiasing != kDefaultSubpixelAntialiasing
307 || fCurrentHinting != kDefaultHintingMode
308 || fCurrentAverageWeight != kDefaultAverageWeight;
309 }
310
311
312 bool
IsRevertable()313 AntialiasingSettingsView::IsRevertable()
314 {
315 return fCurrentSubpixelAntialiasing != fSavedSubpixelAntialiasing
316 || fCurrentHinting != fSavedHinting
317 || fCurrentAverageWeight != fSavedAverageWeight;
318 }
319
320
321 void
Revert()322 AntialiasingSettingsView::Revert()
323 {
324 if (!IsRevertable())
325 return;
326
327 fCurrentSubpixelAntialiasing = fSavedSubpixelAntialiasing;
328 fCurrentHinting = fSavedHinting;
329 fCurrentAverageWeight = fSavedAverageWeight;
330
331 set_subpixel_antialiasing(fCurrentSubpixelAntialiasing);
332 set_hinting_mode(fCurrentHinting);
333 set_average_weight(fCurrentAverageWeight);
334
335 _SetCurrentAntialiasing();
336 _SetCurrentHinting();
337 _SetCurrentAverageWeight();
338 }
339