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 <freetype/config/ftoption.h> 14 // for detected the availablility of subpixel anti-aliasing 15 16 #include <Box.h> 17 #include <Catalog.h> 18 #include <GridLayoutBuilder.h> 19 #include <GroupLayoutBuilder.h> 20 #include <Locale.h> 21 #include <MenuField.h> 22 #include <MenuItem.h> 23 #include <PopUpMenu.h> 24 #include <Slider.h> 25 #include <SpaceLayoutItem.h> 26 #include <String.h> 27 #include <TextView.h> 28 29 #include "APRWindow.h" 30 31 #undef B_TRANSLATE_CONTEXT 32 #define B_TRANSLATE_CONTEXT "AntialiasingSettingsView" 33 34 35 //#define DISABLE_HINTING_CONTROL 36 // if defined, the hinting menu is disabled (hinting not properly 37 // implemented) 38 39 static const int32 kMsgSetAntialiasing = 'anti'; 40 static const int32 kMsgSetHinting = 'hint'; 41 static const int32 kMsgSetAverageWeight = 'avrg'; 42 static const char* kSubpixelLabel = B_TRANSLATE_MARK("LCD subpixel"); 43 static const char* kGrayscaleLabel = B_TRANSLATE_MARK("Grayscale"); 44 static const char* kNoHintingLabel = B_TRANSLATE_MARK("Off"); 45 static const char* kMonospacedHintingLabel = 46 B_TRANSLATE_MARK("Monospaced fonts only"); 47 static const char* kFullHintingLabel = B_TRANSLATE_MARK("On"); 48 49 50 // #pragma mark - private libbe API 51 52 53 enum { 54 HINTING_MODE_OFF = 0, 55 HINTING_MODE_ON, 56 HINTING_MODE_MONOSPACED_ONLY 57 }; 58 59 extern void set_subpixel_antialiasing(bool subpix); 60 extern status_t get_subpixel_antialiasing(bool* subpix); 61 extern void set_hinting_mode(uint8 hinting); 62 extern status_t get_hinting_mode(uint8* hinting); 63 extern void set_average_weight(unsigned char averageWeight); 64 extern status_t get_average_weight(unsigned char* averageWeight); 65 66 67 // #pragma mark - 68 69 70 AntialiasingSettingsView::AntialiasingSettingsView(const char* name) 71 : BView(name, 0) 72 { 73 // collect the current system settings 74 if (get_subpixel_antialiasing(&fCurrentSubpixelAntialiasing) != B_OK) 75 fCurrentSubpixelAntialiasing = false; 76 fSavedSubpixelAntialiasing = fCurrentSubpixelAntialiasing; 77 78 if (get_hinting_mode(&fCurrentHinting) != B_OK) 79 fCurrentHinting = HINTING_MODE_ON; 80 fSavedHinting = fCurrentHinting; 81 82 if (get_average_weight(&fCurrentAverageWeight) != B_OK) 83 fCurrentAverageWeight = 100; 84 fSavedAverageWeight = fCurrentAverageWeight; 85 86 // create the controls 87 88 // antialiasing menu 89 _BuildAntialiasingMenu(); 90 fAntialiasingMenuField = new BMenuField("antialiasing", 91 B_TRANSLATE("Antialiasing type:"), fAntialiasingMenu); 92 93 // "average weight" in subpixel filtering 94 fAverageWeightControl = new BSlider("averageWeightControl", 95 B_TRANSLATE("Reduce colored edges filter strength:"), 96 new BMessage(kMsgSetAverageWeight), 0, 255, B_HORIZONTAL); 97 fAverageWeightControl->SetLimitLabels(B_TRANSLATE("Off"), 98 B_TRANSLATE("Strong")); 99 fAverageWeightControl->SetHashMarks(B_HASH_MARKS_BOTTOM); 100 fAverageWeightControl->SetHashMarkCount(255 / 15); 101 fAverageWeightControl->SetEnabled(false); 102 103 // hinting menu 104 _BuildHintingMenu(); 105 fHintingMenuField = new BMenuField("hinting", B_TRANSLATE("Glyph hinting:"), 106 fHintingMenu); 107 108 #ifdef DISABLE_HINTING_CONTROL 109 fHintingMenuField->SetEnabled(false); 110 #endif 111 112 #ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING 113 // subpixelAntialiasingDisabledLabel 114 BFont infoFont(*be_plain_font); 115 infoFont.SetFace(B_ITALIC_FACE); 116 rgb_color infoColor = tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), 117 B_DARKEN_4_TINT); 118 // TODO: Replace with layout friendly constructor once available. 119 BRect textBounds = Bounds(); 120 BTextView* subpixelAntialiasingDisabledLabel = new BTextView( 121 textBounds, "unavailable label", textBounds, &infoFont, &infoColor, 122 B_FOLLOW_NONE, B_WILL_DRAW | B_SUPPORTS_LAYOUT); 123 subpixelAntialiasingDisabledLabel->SetText(B_TRANSLATE( 124 "Subpixel based anti-aliasing in combination with glyph hinting is not " 125 "available in this build of Haiku to avoid possible patent issues. To " 126 "enable this feature, you have to build Haiku yourself and enable " 127 "certain options in the libfreetype configuration header.")); 128 subpixelAntialiasingDisabledLabel->SetViewColor( 129 ui_color(B_PANEL_BACKGROUND_COLOR)); 130 subpixelAntialiasingDisabledLabel->MakeEditable(false); 131 subpixelAntialiasingDisabledLabel->MakeSelectable(false); 132 #endif // !FT_CONFIG_OPTION_SUBPIXEL_RENDERING 133 134 SetLayout(new BGroupLayout(B_VERTICAL)); 135 136 // controls pane 137 AddChild(BGridLayoutBuilder(10, 10) 138 .Add(fHintingMenuField->CreateLabelLayoutItem(), 0, 0) 139 .Add(fHintingMenuField->CreateMenuBarLayoutItem(), 1, 0) 140 141 .Add(fAntialiasingMenuField->CreateLabelLayoutItem(), 0, 1) 142 .Add(fAntialiasingMenuField->CreateMenuBarLayoutItem(), 1, 1) 143 144 .Add(fAverageWeightControl, 0, 2, 2) 145 146 #ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING 147 // hinting+subpixel unavailable info 148 .Add(subpixelAntialiasingDisabledLabel, 0, 3, 2) 149 #else 150 .Add(BSpaceLayoutItem::CreateGlue(), 0, 3, 2) 151 #endif 152 153 .SetInsets(10, 10, 10, 10) 154 ); 155 156 _SetCurrentAntialiasing(); 157 _SetCurrentHinting(); 158 _SetCurrentAverageWeight(); 159 } 160 161 162 AntialiasingSettingsView::~AntialiasingSettingsView() 163 { 164 } 165 166 167 void 168 AntialiasingSettingsView::AttachedToWindow() 169 { 170 if (Parent() != NULL) 171 SetViewColor(Parent()->ViewColor()); 172 else 173 SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 174 175 fAntialiasingMenu->SetTargetForItems(this); 176 fHintingMenu->SetTargetForItems(this); 177 fAverageWeightControl->SetTarget(this); 178 } 179 180 181 void 182 AntialiasingSettingsView::MessageReceived(BMessage *msg) 183 { 184 switch (msg->what) { 185 case kMsgSetAntialiasing: 186 { 187 bool subpixelAntialiasing; 188 if (msg->FindBool("antialiasing", &subpixelAntialiasing) != B_OK 189 || subpixelAntialiasing == fCurrentSubpixelAntialiasing) 190 break; 191 fCurrentSubpixelAntialiasing = subpixelAntialiasing; 192 fAverageWeightControl->SetEnabled(fCurrentSubpixelAntialiasing); 193 194 set_subpixel_antialiasing(fCurrentSubpixelAntialiasing); 195 196 Window()->PostMessage(kMsgUpdate); 197 break; 198 } 199 case kMsgSetHinting: 200 { 201 int8 hinting; 202 if (msg->FindInt8("hinting", &hinting) != B_OK 203 || hinting == fCurrentHinting) 204 break; 205 206 fCurrentHinting = hinting; 207 set_hinting_mode(fCurrentHinting); 208 209 Window()->PostMessage(kMsgUpdate); 210 break; 211 } 212 case kMsgSetAverageWeight: 213 { 214 int32 averageWeight = fAverageWeightControl->Value(); 215 if (averageWeight == fCurrentAverageWeight) 216 break; 217 218 fCurrentAverageWeight = averageWeight; 219 220 set_average_weight(fCurrentAverageWeight); 221 222 Window()->PostMessage(kMsgUpdate); 223 break; 224 } 225 default: 226 BView::MessageReceived(msg); 227 } 228 } 229 230 231 void 232 AntialiasingSettingsView::_BuildAntialiasingMenu() 233 { 234 fAntialiasingMenu = new BPopUpMenu(B_TRANSLATE("Antialiasing menu")); 235 236 BMessage* message = new BMessage(kMsgSetAntialiasing); 237 message->AddBool("antialiasing", false); 238 239 BMenuItem* item 240 = new BMenuItem(B_TRANSLATE_NOCOLLECT(kGrayscaleLabel), message); 241 242 fAntialiasingMenu->AddItem(item); 243 244 message = new BMessage(kMsgSetAntialiasing); 245 message->AddBool("antialiasing", true); 246 247 item = new BMenuItem(B_TRANSLATE_NOCOLLECT(kSubpixelLabel), message); 248 249 fAntialiasingMenu->AddItem(item); 250 } 251 252 253 void 254 AntialiasingSettingsView::_BuildHintingMenu() 255 { 256 fHintingMenu = new BPopUpMenu(B_TRANSLATE("Hinting menu")); 257 258 BMessage* message = new BMessage(kMsgSetHinting); 259 message->AddInt8("hinting", HINTING_MODE_OFF); 260 fHintingMenu->AddItem(new BMenuItem(B_TRANSLATE_NOCOLLECT(kNoHintingLabel), 261 message)); 262 263 message = new BMessage(kMsgSetHinting); 264 message->AddInt8("hinting", HINTING_MODE_ON); 265 fHintingMenu->AddItem(new BMenuItem( 266 B_TRANSLATE_NOCOLLECT(kFullHintingLabel), message)); 267 268 message = new BMessage(kMsgSetHinting); 269 message->AddInt8("hinting", HINTING_MODE_MONOSPACED_ONLY); 270 fHintingMenu->AddItem(new BMenuItem( 271 B_TRANSLATE_NOCOLLECT(kMonospacedHintingLabel), message)); 272 } 273 274 275 void 276 AntialiasingSettingsView::_SetCurrentAntialiasing() 277 { 278 BMenuItem *item = fAntialiasingMenu->FindItem( 279 fCurrentSubpixelAntialiasing 280 ? B_TRANSLATE_NOCOLLECT(kSubpixelLabel) 281 : B_TRANSLATE_NOCOLLECT(kGrayscaleLabel)); 282 if (item != NULL) 283 item->SetMarked(true); 284 if (fCurrentSubpixelAntialiasing) 285 fAverageWeightControl->SetEnabled(true); 286 } 287 288 289 void 290 AntialiasingSettingsView::_SetCurrentHinting() 291 { 292 const char* label; 293 switch (fCurrentHinting) { 294 case HINTING_MODE_OFF: 295 label = kNoHintingLabel; 296 break; 297 case HINTING_MODE_ON: 298 label = kFullHintingLabel; 299 break; 300 case HINTING_MODE_MONOSPACED_ONLY: 301 label = kMonospacedHintingLabel; 302 break; 303 default: 304 return; 305 } 306 307 BMenuItem *item = fHintingMenu->FindItem(B_TRANSLATE_NOCOLLECT(label)); 308 if (item != NULL) 309 item->SetMarked(true); 310 } 311 312 313 void 314 AntialiasingSettingsView::_SetCurrentAverageWeight() 315 { 316 fAverageWeightControl->SetValue(fCurrentAverageWeight); 317 } 318 319 320 void 321 AntialiasingSettingsView::SetDefaults() 322 { 323 } 324 325 326 bool 327 AntialiasingSettingsView::IsDefaultable() 328 { 329 return false; 330 } 331 332 333 bool 334 AntialiasingSettingsView::IsRevertable() 335 { 336 return fCurrentSubpixelAntialiasing != fSavedSubpixelAntialiasing 337 || fCurrentHinting != fSavedHinting 338 || fCurrentAverageWeight != fSavedAverageWeight; 339 } 340 341 342 void 343 AntialiasingSettingsView::Revert() 344 { 345 if (!IsRevertable()) 346 return; 347 348 fCurrentSubpixelAntialiasing = fSavedSubpixelAntialiasing; 349 fCurrentHinting = fSavedHinting; 350 fCurrentAverageWeight = fSavedAverageWeight; 351 352 set_subpixel_antialiasing(fCurrentSubpixelAntialiasing); 353 set_hinting_mode(fCurrentHinting); 354 set_average_weight(fCurrentAverageWeight); 355 356 _SetCurrentAntialiasing(); 357 _SetCurrentHinting(); 358 _SetCurrentAverageWeight(); 359 } 360