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 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 124 AntialiasingSettingsView::~AntialiasingSettingsView() 125 { 126 } 127 128 129 void 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 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 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 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 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 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 277 AntialiasingSettingsView::_SetCurrentAverageWeight() 278 { 279 fAverageWeightControl->SetValue(fCurrentAverageWeight); 280 } 281 282 283 void 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 304 AntialiasingSettingsView::IsDefaultable() 305 { 306 return fCurrentSubpixelAntialiasing != kDefaultSubpixelAntialiasing 307 || fCurrentHinting != kDefaultHintingMode 308 || fCurrentAverageWeight != kDefaultAverageWeight; 309 } 310 311 312 bool 313 AntialiasingSettingsView::IsRevertable() 314 { 315 return fCurrentSubpixelAntialiasing != fSavedSubpixelAntialiasing 316 || fCurrentHinting != fSavedHinting 317 || fCurrentAverageWeight != fSavedAverageWeight; 318 } 319 320 321 void 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