diff --git a/headers/libs/agg/agg_renderer_base.h b/headers/libs/agg/agg_renderer_base.h index b42168b05c..6521d7a405 100644 --- a/headers/libs/agg/agg_renderer_base.h +++ b/headers/libs/agg/agg_renderer_base.h @@ -206,21 +206,6 @@ namespace agg m_ren->blend_hline(x1, y, x2 - x1 + 1, c, cover); } - //-------------------------------------------------------------------- - void blend_hline_subpix(int x1, int y, int x2, - const color_type& c, cover_type cover) - { - if(x1 > x2) { int t = x2; x2 = x1; x1 = t; } - if(y > ymax()) return; - if(y < ymin()) return; - if(x1 > xmax()) return; - if(x2 < xmin()) return; - - if(x1 < xmin()) x1 = xmin(); - if(x2 > xmax()) x2 = xmax(); - - m_ren->blend_hline_subpix(x1, y, x2 - x1 + 1, c, cover); - } //-------------------------------------------------------------------- void blend_vline(int x, int y1, int y2, @@ -309,7 +294,7 @@ namespace agg { len -= 3 * (xmin() - x); if(len <= 0) return; - covers += 3*(xmin() - x); + covers += 3 * (xmin() - x); x = xmin(); } if(x + len / 3 > xmax()) diff --git a/headers/private/app/ServerProtocol.h b/headers/private/app/ServerProtocol.h index 04494c7065..73067f465a 100644 --- a/headers/private/app/ServerProtocol.h +++ b/headers/private/app/ServerProtocol.h @@ -189,10 +189,15 @@ enum { AS_GET_SHOW_ALL_DRAGGERS, AS_SET_SHOW_ALL_DRAGGERS, - AS_SET_FONT_SUBPIXEL_ANTIALIASING, - AS_GET_FONT_SUBPIXEL_ANTIALIASING, + // Subpixel antialiasing & hinting + AS_SET_SUBPIXEL_ANTIALIASING, + AS_GET_SUBPIXEL_ANTIALIASING, AS_SET_HINTING, AS_GET_HINTING, + AS_SET_SUBPIXEL_AVERAGE_WEIGHT, + AS_GET_SUBPIXEL_AVERAGE_WEIGHT, + AS_SET_SUBPIXEL_ORDERING, + AS_GET_SUBPIXEL_ORDERING, // Graphics calls AS_SET_HIGH_COLOR, diff --git a/src/kits/interface/Font.cpp b/src/kits/interface/Font.cpp index 3139740aae..4d96e11b9f 100644 --- a/src/kits/interface/Font.cpp +++ b/src/kits/interface/Font.cpp @@ -406,59 +406,6 @@ _get_system_default_font_(const char* which, font_family family, } -void -_set_font_subpixel_antialiasing_(bool subpix) -{ - BPrivate::AppServerLink link; - - link.StartMessage(AS_SET_FONT_SUBPIXEL_ANTIALIASING); - link.Attach(subpix); - link.Flush(); -} - - -status_t -_get_font_subpixel_antialiasing_(bool* subpix) -{ - BPrivate::AppServerLink link; - - link.StartMessage(AS_GET_FONT_SUBPIXEL_ANTIALIASING); - int32 status = B_ERROR; - if (link.FlushWithReply(status) != B_OK - || status < B_OK) - return status; - link.Read(subpix); - return B_OK; -} - - -void -_set_hinting_(bool hinting) -{ - BPrivate::AppServerLink link; - - link.StartMessage(AS_SET_HINTING); - link.Attach(hinting); - link.Flush(); -} - - -status_t -_get_hinting_(bool* hinting) -{ - - BPrivate::AppServerLink link; - - link.StartMessage(AS_GET_HINTING); - int32 status = B_ERROR; - if (link.FlushWithReply(status) != B_OK - || status < B_OK) - return status; - link.Read(hinting); - return B_OK; -} - - /*! \brief Returns the number of installed font families \return The number of installed font families diff --git a/src/kits/interface/InterfaceDefs.cpp b/src/kits/interface/InterfaceDefs.cpp index ba89b2c229..2a6fd2c6cd 100644 --- a/src/kits/interface/InterfaceDefs.cpp +++ b/src/kits/interface/InterfaceDefs.cpp @@ -195,6 +195,107 @@ get_mode_parameter(uint32 mode, int32& width, int32& height, uint32& colorSpace) } // namespace BPrivate +void +set_subpixel_antialiasing(bool subpix) +{ + BPrivate::AppServerLink link; + + link.StartMessage(AS_SET_SUBPIXEL_ANTIALIASING); + link.Attach(subpix); + link.Flush(); +} + + +status_t +get_subpixel_antialiasing(bool* subpix) +{ + BPrivate::AppServerLink link; + + link.StartMessage(AS_GET_SUBPIXEL_ANTIALIASING); + int32 status = B_ERROR; + if (link.FlushWithReply(status) != B_OK || status < B_OK) + return status; + link.Read(subpix); + return B_OK; +} + + +void +set_hinting(bool hinting) +{ + BPrivate::AppServerLink link; + + link.StartMessage(AS_SET_HINTING); + link.Attach(hinting); + link.Flush(); +} + + +status_t +get_hinting(bool* hinting) +{ + BPrivate::AppServerLink link; + + link.StartMessage(AS_GET_HINTING); + int32 status = B_ERROR; + if (link.FlushWithReply(status) != B_OK || status < B_OK) + return status; + link.Read(hinting); + return B_OK; +} + + +void +set_average_weight(uint8 averageWeight) +{ + BPrivate::AppServerLink link; + + link.StartMessage(AS_SET_SUBPIXEL_AVERAGE_WEIGHT); + link.Attach(averageWeight); + link.Flush(); +} + + +status_t +get_average_weight(uint8* averageWeight) +{ + BPrivate::AppServerLink link; + + link.StartMessage(AS_GET_SUBPIXEL_AVERAGE_WEIGHT); + int32 status = B_ERROR; + if (link.FlushWithReply(status) != B_OK || status < B_OK) + return status; + link.Read(averageWeight); + return B_OK; +} + + +void +set_is_subpixel_ordering_regular(bool subpixelOrdering) +{ + BPrivate::AppServerLink link; + + link.StartMessage(AS_SET_SUBPIXEL_ORDERING); + link.Attach(subpixelOrdering); + link.Flush(); +} + + +status_t +get_is_subpixel_ordering_regular(bool* subpixelOrdering) +{ + + BPrivate::AppServerLink link; + + link.StartMessage(AS_GET_SUBPIXEL_ORDERING); + int32 status = B_ERROR; + if (link.FlushWithReply(status) != B_OK || status < B_OK) + return status; + link.Read(subpixelOrdering); + return B_OK; +} + + const color_map * system_colors() { @@ -965,6 +1066,7 @@ set_decorator(const int32 &index) return B_OK; } + } // namespace BPrivate // These methods were marked with "Danger, will Robinson!" in diff --git a/src/preferences/appearance/APRView.cpp b/src/preferences/appearance/APRView.cpp index c1311507b5..50060ff15d 100644 --- a/src/preferences/appearance/APRView.cpp +++ b/src/preferences/appearance/APRView.cpp @@ -18,6 +18,7 @@ #include #include "APRView.h" +#include "APRWindow.h" #include "defs.h" #include "ColorWell.h" #include "ColorWhichItem.h" @@ -152,26 +153,7 @@ APRView::APRView(const BRect &frame, const char *name, int32 resize, int32 flags fPicker = new BColorControl(BPoint(fScrollView->Frame().left,fScrollView->Frame().bottom+kBorderSpace),B_CELLS_32x8,5.0,"fPicker", new BMessage(UPDATE_COLOR)); - AddChild(fPicker); - - fDefaults = new BButton(BRect(0,0,1,1),"DefaultsButton","Defaults", - new BMessage(DEFAULT_SETTINGS), - B_FOLLOW_LEFT |B_FOLLOW_TOP, B_WILL_DRAW | B_NAVIGABLE); - fDefaults->ResizeToPreferred(); - fDefaults->SetEnabled(false); - fDefaults->MoveTo(fPicker->Frame().left,fPicker->Frame().bottom+kBorderSpace); - AddChild(fDefaults); - - - BRect cvrect(fDefaults->Frame()); - cvrect.OffsetBy(cvrect.Width() + kItemSpace,0); - - fRevert = new BButton(cvrect,"RevertButton","Revert", - new BMessage(REVERT_SETTINGS), - B_FOLLOW_LEFT |B_FOLLOW_TOP, B_WILL_DRAW | B_NAVIGABLE); - fRevert->ResizeToPreferred(); - fRevert->SetEnabled(false); - AddChild(fRevert); + AddChild(fPicker); } APRView::~APRView(void) @@ -184,21 +166,15 @@ APRView::AttachedToWindow(void) { fPicker->SetTarget(this); fAttrList->SetTarget(this); - fDefaults->SetTarget(this); - fRevert->SetTarget(this); fColorWell->SetTarget(this); fPicker->SetValue(fCurrentSet.StringToColor(fAttrString.String())); if (fDecorMenu) fDecorMenu->SetTargetForItems(BMessenger(this)); - - Window()->ResizeTo(MAX(fPicker->Frame().right,fPicker->Frame().right) + 10, - fDefaults->Frame().bottom + 10); + LoadSettings(); fAttrList->Select(0); - - fDefaults->SetEnabled(fCurrentSet.IsDefaultable()); } void @@ -235,11 +211,9 @@ APRView::MessageReceived(BMessage *msg) // Update current fAttribute in the settings fCurrentSet.SetColor(fAttribute, col); - UpdateCurrentColor(); - - fDefaults->SetEnabled(fCurrentSet.IsDefaultable()); - fRevert->SetEnabled(true); - + UpdateCurrentColor(); + + Window()->PostMessage(kMsgUpdate); break; } case ATTRIBUTE_CHOSEN: { @@ -254,7 +228,7 @@ APRView::MessageReceived(BMessage *msg) fAttrString=whichitem->Text(); UpdateControlsFromAttr(whichitem->Text()); - fDefaults->SetEnabled(fCurrentSet.IsDefaultable()); + Window()->PostMessage(kMsgUpdate); break; } case REVERT_SETTINGS: { @@ -262,13 +236,11 @@ APRView::MessageReceived(BMessage *msg) UpdateControlsFromAttr(fAttrString.String()); UpdateAllColors(); - fRevert->SetEnabled(false); - + Window()->PostMessage(kMsgUpdate); break; } case DEFAULT_SETTINGS: { fCurrentSet = ColorSet::DefaultColorSet(); - fDefaults->SetEnabled(false); UpdateControlsFromAttr(fAttrString.String()); UpdateAllColors(); @@ -281,6 +253,7 @@ APRView::MessageReceived(BMessage *msg) BPrivate::set_decorator(fDecorMenu->IndexOf(item)); #endif } + Window()->PostMessage(kMsgUpdate); break; } default: @@ -302,6 +275,11 @@ void APRView::LoadSettings(void) fPrevSet = fCurrentSet; } +bool APRView::IsDefaultable(void) +{ + return fCurrentSet.IsDefaultable(); +} + void APRView::UpdateAllColors(void) { for (uint32 i = 0; i < sColorCount; i++) diff --git a/src/preferences/appearance/APRView.h b/src/preferences/appearance/APRView.h index ee715fe809..04f38c5235 100644 --- a/src/preferences/appearance/APRView.h +++ b/src/preferences/appearance/APRView.h @@ -40,6 +40,7 @@ public: void MessageReceived(BMessage *msg); void LoadSettings(void); + bool IsDefaultable(void); protected: @@ -49,9 +50,6 @@ protected: BColorControl *fPicker; - BButton *fRevert; - BButton *fDefaults; - BListView *fAttrList; color_which fAttribute; diff --git a/src/preferences/appearance/APRWindow.cpp b/src/preferences/appearance/APRWindow.cpp index c499bc3df4..ca89090c17 100644 --- a/src/preferences/appearance/APRWindow.cpp +++ b/src/preferences/appearance/APRWindow.cpp @@ -6,19 +6,101 @@ * DarkWyrm (darkwyrm@earthlink.net) */ +#include #include +#include #include "APRWindow.h" #include "APRView.h" #include "defs.h" +static const uint32 kMsgSetDefaults = 'dflt'; +static const uint32 kMsgRevert = 'rvrt'; + APRWindow::APRWindow(BRect frame) - : BWindow(frame, "Appearance", B_TITLED_WINDOW, B_NOT_RESIZABLE | B_NOT_ZOOMABLE, - B_ALL_WORKSPACES ) + : BWindow(frame, "Appearance", B_TITLED_WINDOW, B_NOT_ZOOMABLE, + B_ALL_WORKSPACES) { - APRView *colorview = new APRView(Bounds(),"Colors",B_FOLLOW_ALL, B_WILL_DRAW); - AddChild(colorview); + BRect rect = Bounds(); + BView* view = new BView(rect, "background", B_FOLLOW_ALL, B_WILL_DRAW); + view->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); + AddChild(view); + + rect.left = 10; + rect.top = rect.bottom - 10; + fDefaultsButton = new BButton(rect, "defaults", "Defaults", + new BMessage(kMsgSetDefaults), B_FOLLOW_LEFT + | B_FOLLOW_BOTTOM, B_WILL_DRAW); + fDefaultsButton->ResizeToPreferred(); + fDefaultsButton->SetEnabled(false); + float buttonHeight = fDefaultsButton->Bounds().Height(); + fDefaultsButton->MoveBy(0, -buttonHeight); + view->AddChild(fDefaultsButton); + + rect = fDefaultsButton->Frame(); + rect.OffsetBy(fDefaultsButton->Bounds().Width() + 10, 0); + + fRevertButton = new BButton(rect, "revert", "Revert", + new BMessage(kMsgRevert), B_FOLLOW_LEFT | B_FOLLOW_BOTTOM, B_WILL_DRAW); + fRevertButton->ResizeToPreferred(); + fRevertButton->SetEnabled(false); + view->AddChild(fRevertButton); + + rect = Bounds(); + rect.top += 5; + rect.bottom -= 20 + buttonHeight; + rect.left += 5; + BTabView *tabView = new BTabView(rect, "tabview", B_WIDTH_FROM_LABEL); + + rect = tabView->ContainerView()->Bounds().InsetByCopy(5, 8); + + fAntialiasingSettings = new AntialiasingSettingsView(rect, "Antialiasing"); + fColorsView = new APRView(rect,"Colors",B_FOLLOW_ALL, B_WILL_DRAW); + + tabView->AddTab(fColorsView); + tabView->AddTab(fAntialiasingSettings); + + view->AddChild(tabView); + fColorsView->ResizeToPreferred(); + fAntialiasingSettings -> ResizeToPreferred(); + + fDefaultsButton -> SetEnabled(fColorsView -> IsDefaultable() + || fAntialiasingSettings -> IsDefaultable()); + fDefaultsButton -> SetTarget(this); + fRevertButton -> SetTarget(this); } + +void +APRWindow::MessageReceived(BMessage *message) +{ + switch (message->what) { + case kMsgUpdate: + fDefaultsButton->SetEnabled(fColorsView->IsDefaultable() + || fAntialiasingSettings->IsDefaultable()); + fRevertButton->SetEnabled(true); + break; + case kMsgSetDefaults: + fColorsView -> MessageReceived(new BMessage(DEFAULT_SETTINGS)); + fAntialiasingSettings->SetDefaults(); + fDefaultsButton->SetEnabled(false); + fRevertButton->SetEnabled(true); + break; + + case kMsgRevert: + fColorsView -> MessageReceived(new BMessage(REVERT_SETTINGS)); + fAntialiasingSettings->Revert(); + fDefaultsButton->SetEnabled(fColorsView->IsDefaultable() + || fAntialiasingSettings->IsDefaultable()); + fRevertButton->SetEnabled(false); + break; + + default: + BWindow::MessageReceived(message); + break; + } +} + + bool APRWindow::QuitRequested(void) { diff --git a/src/preferences/appearance/APRWindow.h b/src/preferences/appearance/APRWindow.h index 7fe6bf5859..8207df655d 100644 --- a/src/preferences/appearance/APRWindow.h +++ b/src/preferences/appearance/APRWindow.h @@ -9,14 +9,30 @@ #define APR_WINDOW_H #include +#include #include #include +#include + +#include "APRView.h" +#include "AntialiasingSettingsView.h" class APRWindow : public BWindow { public: APRWindow(BRect frame); bool QuitRequested(void); + void MessageReceived(BMessage *message); + +private: + APRView* fColorsView; + BButton* fDefaultsButton; + BButton* fRevertButton; + + AntialiasingSettingsView* fAntialiasingSettings; + }; +static const int32 kMsgUpdate = 'updt'; + #endif diff --git a/src/preferences/fonts/AdvancedSettingsView.cpp b/src/preferences/appearance/AntialiasingSettingsView.cpp similarity index 52% rename from src/preferences/fonts/AdvancedSettingsView.cpp rename to src/preferences/appearance/AntialiasingSettingsView.cpp index 37d1556ccb..34b5b5ea18 100644 --- a/src/preferences/fonts/AdvancedSettingsView.cpp +++ b/src/preferences/appearance/AntialiasingSettingsView.cpp @@ -1,59 +1,64 @@ /* - * Copyright 2008, Haiku. All rights reserved. - * Distributed under the terms of the MIT License. - * - * Authors: - * Andrej Spielmann, + * Copyright 2008, Andrej Spielmann, + * All rights reserved. Distributed under the terms of the MIT License. */ +#include "AntialiasingSettingsView.h" -#include "AdvancedSettingsView.h" -#include "MainWindow.h" +#include +#include #include #include #include #include #include +#include -#include +#include "APRWindow.h" #define INSTANT_UPDATE // if defined, the changes will take place immediately and not only on exit -#define DISABLE_HINTING_CONTROL +//#define DISABLE_HINTING_CONTROL // if defined, the hinting menu is disabled (hinting not properly // implemented) static const int32 kMsgSetAntialiasing = 'anti'; static const int32 kMsgSetHinting = 'hint'; +static const int32 kMsgSetAverageWeight = 'avrg'; static const char* kSubpixelLabel = "Subpixel antialiasing"; static const char* kGrayscaleLabel = "Grayscale antialiasing"; static const char* kNoHintingLabel = "Off"; static const char* kFullHintingLabel = "On"; -// private font API -extern void _set_font_subpixel_antialiasing_(bool subpix); -extern status_t _get_font_subpixel_antialiasing_(bool* subpix); -extern void _set_hinting_(bool subpix); -extern status_t _get_hinting_(bool* subpix); +extern void set_subpixel_antialiasing(bool subpix); +extern status_t get_subpixel_antialiasing(bool* subpix); +extern void set_hinting(bool hinting); +extern status_t get_hinting(bool* hinting); +extern void set_average_weight(unsigned char averageWeight); +extern status_t get_average_weight(unsigned char* averageWeight); // #pragma mark - -AdvancedSettingsView::AdvancedSettingsView(BRect _rect, const char* name) +AntialiasingSettingsView::AntialiasingSettingsView(BRect _rect, const char* name) : BView(_rect, name, B_FOLLOW_LEFT_RIGHT, B_WILL_DRAW) { - if (_get_font_subpixel_antialiasing_(&fCurrentSubpixelAntialiasing) != B_OK) + if (get_subpixel_antialiasing(&fCurrentSubpixelAntialiasing) != B_OK) fCurrentSubpixelAntialiasing = false; fSavedSubpixelAntialiasing = fCurrentSubpixelAntialiasing; - if (_get_hinting_(&fCurrentHinting) != B_OK) + if (get_hinting(&fCurrentHinting) != B_OK) fCurrentHinting = true; fSavedHinting = fCurrentHinting; + + if (get_average_weight(&fCurrentAverageWeight) != B_OK) + fCurrentAverageWeight = 100; + fSavedAverageWeight = fCurrentAverageWeight; - fDivider = StringWidth("Character hinting:") + 5; + fDivider = StringWidth("Strength of colours in sbpx AA:") + 5; fAntialiasingMenu = new BPopUpMenu("Antialiasing menu"); fHintingMenu = new BPopUpMenu("Hinting menu"); @@ -68,8 +73,27 @@ AdvancedSettingsView::AdvancedSettingsView(BRect _rect, const char* name) AddChild(fAntialiasingMenuField); _BuildAntialiasingMenu(); - // hinting menu + //Average weight in subpixel filtering float shift = fAntialiasingMenuField->Bounds().Height()+5; + rect.top +=shift; + rect.bottom += shift; + fAverageWeightControl = new BTextControl(rect, "averageWeightControl", + "Strength of colours in sbpx AA:", NULL, + new BMessage(kMsgSetAverageWeight), B_FOLLOW_LEFT | B_FOLLOW_BOTTOM); + fAverageWeightControl -> SetDivider(fDivider); + fAverageWeightControl -> TextView() -> SetMaxBytes(3); + fAverageWeightControl -> ResizeToPreferred(); + AddChild(fAverageWeightControl); + for (int i = 0; i < 256; i++) { + if (i < '0' || i > '9') { + fAverageWeightControl->TextView()->DisallowChar(i); + fAverageWeightControl->TextView()->DisallowChar(i); + } + } + fAverageWeightControl -> SetEnabled(false); + + // hinting menu + shift = fAverageWeightControl->Bounds().Height()+5; rect.top += shift; rect.bottom += shift; fHintingMenuField = new BMenuField(rect, "hinting", @@ -86,20 +110,22 @@ AdvancedSettingsView::AdvancedSettingsView(BRect _rect, const char* name) _SetCurrentAntialiasing(); _SetCurrentHinting(); + _SetCurrentAverageWeight(); } -AdvancedSettingsView::~AdvancedSettingsView() +AntialiasingSettingsView::~AntialiasingSettingsView() { #ifndef INSTANT_UPDATE - _set_font_subpixel_antialiasing_(fCurrentSubpixelAntialiasing); - _set_hinting(fCurrentHinting); + set_subpixel_antialiasing(fCurrentSubpixelAntialiasing); + set_hinting(fCurrentHinting); + set_average_weight(fCurrentAverageWeight); #endif } void -AdvancedSettingsView::GetPreferredSize(float *_width, float *_height) +AntialiasingSettingsView::GetPreferredSize(float *_width, float *_height) { // don't change the width if it is large enough if (_width) { @@ -115,16 +141,17 @@ AdvancedSettingsView::GetPreferredSize(float *_width, float *_height) void -AdvancedSettingsView::SetDivider(float divider) +AntialiasingSettingsView::SetDivider(float divider) { - fAntialiasingMenuField->SetDivider(divider); - fHintingMenuField->SetDivider(divider); + fAntialiasingMenuField -> SetDivider(divider); + fHintingMenuField -> SetDivider(divider); + fAverageWeightControl -> SetDivider(divider); fDivider = divider; } void -AdvancedSettingsView::RelayoutIfNeeded() +AntialiasingSettingsView::RelayoutIfNeeded() { float width, height; GetPreferredSize(&width, &height); @@ -136,19 +163,20 @@ AdvancedSettingsView::RelayoutIfNeeded() void -AdvancedSettingsView::AttachedToWindow() +AntialiasingSettingsView::AttachedToWindow() { if (Parent() != NULL) SetViewColor(Parent()->ViewColor()); else SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); - fAntialiasingMenu->SetTargetForItems(this); - fHintingMenu->SetTargetForItems(this); + fAntialiasingMenu -> SetTargetForItems(this); + fHintingMenu -> SetTargetForItems(this); + fAverageWeightControl -> SetTarget(this); } void -AdvancedSettingsView::MessageReceived(BMessage *msg) +AntialiasingSettingsView::MessageReceived(BMessage *msg) { switch (msg->what) { case kMsgSetAntialiasing: @@ -158,8 +186,9 @@ AdvancedSettingsView::MessageReceived(BMessage *msg) || subpixelAntialiasing == fCurrentSubpixelAntialiasing) break; fCurrentSubpixelAntialiasing = subpixelAntialiasing; + fAverageWeightControl -> SetEnabled(fCurrentSubpixelAntialiasing); #ifdef INSTANT_UPDATE - _set_font_subpixel_antialiasing_(fCurrentSubpixelAntialiasing); + set_subpixel_antialiasing(fCurrentSubpixelAntialiasing); #endif Window()->PostMessage(kMsgUpdate); break; @@ -172,7 +201,30 @@ AdvancedSettingsView::MessageReceived(BMessage *msg) break; fCurrentHinting = hinting; #ifdef INSTANT_UPDATE - _set_hinting_(fCurrentHinting); + set_hinting(fCurrentHinting); +#endif + Window()->PostMessage(kMsgUpdate); + break; + } + case kMsgSetAverageWeight: + { + int subpixelWeight; + unsigned char averageWeight; + if (fAverageWeightControl -> Text() != NULL) { + subpixelWeight = atoi(fAverageWeightControl -> Text()); + if (subpixelWeight > 255) { + subpixelWeight = 255; + BString subpixelWeightString; + subpixelWeightString << subpixelWeight; + fAverageWeightControl -> SetText( + subpixelWeightString.String()); + } + averageWeight = 255 - subpixelWeight; + if (averageWeight == fCurrentAverageWeight) break; + } else break; + fCurrentAverageWeight = averageWeight; +#ifdef INSTANT_UPDATE + set_average_weight(fCurrentAverageWeight); #endif Window()->PostMessage(kMsgUpdate); break; @@ -184,7 +236,7 @@ AdvancedSettingsView::MessageReceived(BMessage *msg) void -AdvancedSettingsView::_BuildAntialiasingMenu() +AntialiasingSettingsView::_BuildAntialiasingMenu() { BMessage* message = new BMessage(kMsgSetAntialiasing); message->AddBool("antialiasing", false); @@ -203,7 +255,7 @@ AdvancedSettingsView::_BuildAntialiasingMenu() void -AdvancedSettingsView::_BuildHintingMenu() +AntialiasingSettingsView::_BuildHintingMenu() { BMessage* message = new BMessage(kMsgSetHinting); message->AddBool("hinting", false); @@ -222,17 +274,18 @@ AdvancedSettingsView::_BuildHintingMenu() void -AdvancedSettingsView::_SetCurrentAntialiasing() +AntialiasingSettingsView::_SetCurrentAntialiasing() { BMenuItem *item = fAntialiasingMenu->FindItem( fCurrentSubpixelAntialiasing ? kSubpixelLabel : kGrayscaleLabel); if (item != NULL) item->SetMarked(true); + if (fCurrentSubpixelAntialiasing) fAverageWeightControl -> SetEnabled(true); } void -AdvancedSettingsView::_SetCurrentHinting() +AntialiasingSettingsView::_SetCurrentHinting() { BMenuItem *item = fHintingMenu->FindItem( fCurrentHinting ? kFullHintingLabel : kNoHintingLabel); @@ -242,38 +295,51 @@ AdvancedSettingsView::_SetCurrentHinting() void -AdvancedSettingsView::SetDefaults() -{ +AntialiasingSettingsView::_SetCurrentAverageWeight() +{ + BString subpixelWeightString; + subpixelWeightString << (255 - fCurrentAverageWeight); + fAverageWeightControl -> SetText(subpixelWeightString.String()); +} + + +void +AntialiasingSettingsView::SetDefaults() +{ } bool -AdvancedSettingsView::IsDefaultable() +AntialiasingSettingsView::IsDefaultable() { return false; } bool -AdvancedSettingsView::IsRevertable() +AntialiasingSettingsView::IsRevertable() { return (fCurrentSubpixelAntialiasing != fSavedSubpixelAntialiasing) - || (fCurrentHinting != fSavedHinting); + || (fCurrentHinting != fSavedHinting) + || (fCurrentAverageWeight != fSavedAverageWeight); } void -AdvancedSettingsView::Revert() +AntialiasingSettingsView::Revert() { if (!IsRevertable()) return; fCurrentSubpixelAntialiasing = fSavedSubpixelAntialiasing; fCurrentHinting = fSavedHinting; + fCurrentAverageWeight = fSavedAverageWeight; #ifdef INSTANT_UPDATE - _set_font_subpixel_antialiasing_(fCurrentSubpixelAntialiasing); - _set_hinting_(fCurrentHinting); + set_subpixel_antialiasing(fCurrentSubpixelAntialiasing); + set_hinting(fCurrentHinting); + set_average_weight(fCurrentAverageWeight); #endif _SetCurrentAntialiasing(); _SetCurrentHinting(); + _SetCurrentAverageWeight(); } diff --git a/src/preferences/appearance/AntialiasingSettingsView.h b/src/preferences/appearance/AntialiasingSettingsView.h new file mode 100644 index 0000000000..b7db0bf44a --- /dev/null +++ b/src/preferences/appearance/AntialiasingSettingsView.h @@ -0,0 +1,59 @@ +/* + * Copyright 2008, Andrej Spielmann, + * All rights reserved. Distributed under the terms of the MIT License. + */ +#ifndef ANTIALIASING_SETTINGS_VIEW_H +#define ANTIALIASING_SETTINGS_VIEW_H + + +#include + +class BBox; +class BMenuField; +class BPopUpMenu; +class BTextControl; + + +class AntialiasingSettingsView : public BView { +public: + AntialiasingSettingsView(BRect rect, + const char* name); + virtual ~AntialiasingSettingsView(); + + virtual void GetPreferredSize(float *_width, float *_height); + virtual void RelayoutIfNeeded(); + virtual void AttachedToWindow(); + virtual void MessageReceived(BMessage *msg); + + void SetDivider(float divider); + + void SetDefaults(); + void Revert(); + bool IsDefaultable(); + bool IsRevertable(); + +private: + void _BuildAntialiasingMenu(); + void _SetCurrentAntialiasing(); + void _BuildHintingMenu(); + void _SetCurrentHinting(); + void _SetCurrentAverageWeight(); + +protected: + float fDivider; + + BMenuField* fAntialiasingMenuField; + BPopUpMenu* fAntialiasingMenu; + BMenuField* fHintingMenuField; + BPopUpMenu* fHintingMenu; + BTextControl* fAverageWeightControl; + + bool fSavedSubpixelAntialiasing; + bool fCurrentSubpixelAntialiasing; + bool fSavedHinting; + bool fCurrentHinting; + unsigned char fSavedAverageWeight; + unsigned char fCurrentAverageWeight; +}; + +#endif // ANTIALIASING_SETTINGS_VIEW_H diff --git a/src/preferences/appearance/Jamfile b/src/preferences/appearance/Jamfile index 825f0b2c92..f727a73229 100644 --- a/src/preferences/appearance/Jamfile +++ b/src/preferences/appearance/Jamfile @@ -5,6 +5,7 @@ UsePrivateHeaders app [ FDirName servers app ] ; Preference Appearance : APRMain.cpp + AntialiasingSettingsView.cpp APRView.cpp APRWindow.cpp ColorSet.cpp diff --git a/src/preferences/fonts/AdvancedSettingsView.h b/src/preferences/fonts/AdvancedSettingsView.h deleted file mode 100644 index f871d6f048..0000000000 --- a/src/preferences/fonts/AdvancedSettingsView.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2001-2005, Haiku. - * Distributed under the terms of the MIT License. - * - * Authors: - * Andrej Spielmann, - */ -#ifndef ADVANCED_SETTINGS_VIEW_H -#define ADVANCED_SETTINGS_VIEW_H - - -#include - -class BBox; -class BMenuField; -class BPopUpMenu; - - -class AdvancedSettingsView : public BView { - public: - AdvancedSettingsView(BRect rect, const char* name); - virtual ~AdvancedSettingsView(); - - virtual void GetPreferredSize(float *_width, float *_height); - virtual void RelayoutIfNeeded(); - virtual void AttachedToWindow(); - virtual void MessageReceived(BMessage *msg); - - void SetDivider(float divider); - - void SetDefaults(); - void Revert(); - bool IsDefaultable(); - bool IsRevertable(); - - private: - void _BuildAntialiasingMenu(); - void _SetCurrentAntialiasing(); - void _BuildHintingMenu(); - void _SetCurrentHinting(); - - protected: - float fDivider; - - BMenuField* fAntialiasingMenuField; - BPopUpMenu* fAntialiasingMenu; - BMenuField* fHintingMenuField; - BPopUpMenu* fHintingMenu; - - bool fSavedSubpixelAntialiasing; - bool fCurrentSubpixelAntialiasing; - bool fSavedHinting; - bool fCurrentHinting; -}; - -#endif /* ADVANCED_SETTINGS_VIEW_H */ diff --git a/src/preferences/fonts/FontView.h b/src/preferences/fonts/FontView.h index 153617908d..abe58c5b6a 100644 --- a/src/preferences/fonts/FontView.h +++ b/src/preferences/fonts/FontView.h @@ -12,7 +12,6 @@ #include "FontSelectionView.h" -#include "AdvancedSettingsView.h" class FontView : public BView { diff --git a/src/preferences/fonts/Jamfile b/src/preferences/fonts/Jamfile index 7a8d7a746a..837525b5b2 100644 --- a/src/preferences/fonts/Jamfile +++ b/src/preferences/fonts/Jamfile @@ -5,7 +5,6 @@ AddSubDirSupportedPlatforms libbe_test ; Preference Fonts : FontSelectionView.cpp - AdvancedSettingsView.cpp FontsSettings.cpp FontView.cpp main.cpp diff --git a/src/preferences/fonts/MainWindow.cpp b/src/preferences/fonts/MainWindow.cpp index c778a1c4e6..4cdb6eaa71 100644 --- a/src/preferences/fonts/MainWindow.cpp +++ b/src/preferences/fonts/MainWindow.cpp @@ -63,8 +63,6 @@ MainWindow::MainWindow() rect = tabView->ContainerView()->Bounds().InsetByCopy(5, 8); fFontsView = new FontView(rect); - fAdvancedSettings = new AdvancedSettingsView(rect, "Advanced"); - tabView->AddTab(fFontsView); fFontsView->UpdateFonts(); @@ -104,23 +102,6 @@ MainWindow::MainWindow() _Center(); } - tabView->AddTab(fAdvancedSettings); - - fAdvancedSettings->RelayoutIfNeeded(); - fAdvancedSettings->GetPreferredSize(&width, &height); - - widthDiff = width + 10 - tabView->ContainerView()->Bounds().Width(); - if (widthDiff > 0) { - tabView->ResizeBy(widthDiff, 0); - tabView->ContainerView()->ResizeBy(widthDiff, 0); - } - - heightDiff = height + 16 - tabView->ContainerView()->Bounds().Height(); - if (heightDiff > 0) { - tabView->ResizeBy(0, heightDiff); - tabView->ContainerView()->ResizeBy(0, heightDiff); - } - fRunner = new BMessageRunner(this, new BMessage(kMsgCheckFonts), 3000000); // every 3 seconds @@ -149,25 +130,19 @@ MainWindow::MessageReceived(BMessage *message) { switch (message->what) { case kMsgUpdate: - fDefaultsButton->SetEnabled(fFontsView->IsDefaultable() - || fAdvancedSettings->IsDefaultable()); - fRevertButton->SetEnabled(fFontsView->IsRevertable() - || fAdvancedSettings->IsRevertable()); + fDefaultsButton->SetEnabled(fFontsView->IsDefaultable()); + fRevertButton->SetEnabled(fFontsView->IsRevertable()); break; case kMsgSetDefaults: fFontsView->SetDefaults(); - fAdvancedSettings->SetDefaults(); fDefaultsButton->SetEnabled(false); - fRevertButton->SetEnabled(fFontsView->IsRevertable() - || fAdvancedSettings->IsRevertable()); + fRevertButton->SetEnabled(fFontsView->IsRevertable()); break; case kMsgRevert: fFontsView->Revert(); - fAdvancedSettings->Revert(); - fDefaultsButton->SetEnabled(fFontsView->IsDefaultable() - || fAdvancedSettings->IsDefaultable()); + fDefaultsButton->SetEnabled(fFontsView->IsDefaultable()); fRevertButton->SetEnabled(false); break; diff --git a/src/preferences/fonts/MainWindow.h b/src/preferences/fonts/MainWindow.h index b154040ec4..8f800545c0 100644 --- a/src/preferences/fonts/MainWindow.h +++ b/src/preferences/fonts/MainWindow.h @@ -12,7 +12,6 @@ #include "FontsSettings.h" -#include "AdvancedSettingsView.h" #include @@ -38,7 +37,6 @@ class MainWindow : public BWindow { BButton* fRevertButton; FontsSettings fSettings; - AdvancedSettingsView* fAdvancedSettings; }; static const int32 kMsgUpdate = 'updt'; diff --git a/src/servers/app/DesktopSettings.cpp b/src/servers/app/DesktopSettings.cpp index 600c1de546..13c0ea7850 100644 --- a/src/servers/app/DesktopSettings.cpp +++ b/src/servers/app/DesktopSettings.cpp @@ -15,6 +15,7 @@ #include "FontCache.h" #include "FontCacheEntry.h" #include "FontManager.h" +#include "GlobalSubpixelSettings.h" #include "ServerConfig.h" #include @@ -73,10 +74,10 @@ DesktopSettingsPrivate::_SetDefaults() memcpy(fShared.colors, BPrivate::kDefaultColors, sizeof(rgb_color) * kNumColors); - fFontSubpixelAntialiasing = false; - FontCacheEntry::SetDefaultRenderType(glyph_ren_native_gray8); - fHinting = true; - FontCacheEntry::SetDefaultHinting(true); + gSubpixelAntialiasing = false; + gDefaultHinting = true; + gSubpixelAverageWeight = 120; + gSubpixelOrderingRGB = true; } @@ -144,7 +145,6 @@ DesktopSettingsPrivate::_Load() const char* family; const char* style; float size; - bool subpix; bool hinting; if (settings.FindString("plain family", &family) == B_OK && settings.FindString("plain style", &style) == B_OK @@ -168,14 +168,8 @@ DesktopSettingsPrivate::_Load() fFixedFont.SetStyle(fontStyle); fFixedFont.SetSize(size); } - if (settings.FindBool("font subpix", &subpix) == B_OK) { - fFontSubpixelAntialiasing = subpix; - FontCacheEntry::SetDefaultRenderType( - (subpix) ? glyph_ren_subpix : glyph_ren_native_gray8); - } if (settings.FindBool("hinting", &hinting) == B_OK) { - fHinting = hinting; - FontCacheEntry::SetDefaultHinting(fHinting); + gDefaultHinting = hinting; } gFontManager->Unlock(); } @@ -233,8 +227,26 @@ DesktopSettingsPrivate::_Load() fMenuInfo.click_to_open = clickToOpen; bool triggersAlwaysShown; - if (settings.FindBool("triggers always shown", &triggersAlwaysShown) == B_OK) + if (settings.FindBool("triggers always shown", &triggersAlwaysShown) + == B_OK) { fMenuInfo.triggers_always_shown = triggersAlwaysShown; + } + + bool subpix; + if (settings.FindBool("subpixel antialiasing", &subpix) == B_OK) + gSubpixelAntialiasing = subpix; + + int8 averageWeight; + if (settings.FindInt8("subpixel average weight", &averageWeight) + == B_OK) { + gSubpixelAverageWeight = averageWeight; + } + + bool subpixelOrdering; + if (settings.FindBool("subpixel ordering", &subpixelOrdering) + == B_OK) { + gSubpixelOrderingRGB = subpixelOrdering; + } for (int32 i = 0; i < kNumColors; i++) { char colorName[12]; @@ -269,7 +281,8 @@ DesktopSettingsPrivate::Save(uint32 mask) } BFile file; - status = file.SetTo(path.Path(), B_CREATE_FILE | B_ERASE_FILE | B_READ_WRITE); + status = file.SetTo(path.Path(), B_CREATE_FILE | B_ERASE_FILE + | B_READ_WRITE); if (status == B_OK) { status = settings.Flatten(&file, NULL); } @@ -293,11 +306,11 @@ DesktopSettingsPrivate::Save(uint32 mask) settings.AddString("fixed style", fFixedFont.Style()); settings.AddFloat("fixed size", fFixedFont.Size()); - settings.AddBool("font subpix",fFontSubpixelAntialiasing); - settings.AddBool("hinting",fHinting); + settings.AddBool("hinting", gDefaultHinting); BFile file; - status = file.SetTo(path.Path(), B_CREATE_FILE | B_ERASE_FILE | B_READ_WRITE); + status = file.SetTo(path.Path(), B_CREATE_FILE | B_ERASE_FILE + | B_READ_WRITE); if (status == B_OK) { status = settings.Flatten(&file, NULL); } @@ -311,7 +324,8 @@ DesktopSettingsPrivate::Save(uint32 mask) settings.AddInt32("mode", (int32)fMouseMode); BFile file; - status = file.SetTo(path.Path(), B_CREATE_FILE | B_ERASE_FILE | B_READ_WRITE); + status = file.SetTo(path.Path(), B_CREATE_FILE | B_ERASE_FILE + | B_READ_WRITE); if (status == B_OK) { status = settings.Flatten(&file, NULL); } @@ -325,7 +339,8 @@ DesktopSettingsPrivate::Save(uint32 mask) settings.AddBool("show", fShowAllDraggers); BFile file; - status = file.SetTo(path.Path(), B_CREATE_FILE | B_ERASE_FILE | B_READ_WRITE); + status = file.SetTo(path.Path(), B_CREATE_FILE | B_ERASE_FILE + | B_READ_WRITE); if (status == B_OK) { status = settings.Flatten(&file, NULL); } @@ -339,10 +354,16 @@ DesktopSettingsPrivate::Save(uint32 mask) settings.AddFloat("font size", fMenuInfo.font_size); settings.AddString("font family", fMenuInfo.f_family); settings.AddString("font style", fMenuInfo.f_style); - settings.AddInt32("bg color", (const int32&)fMenuInfo.background_color); + settings.AddInt32("bg color", + (const int32&)fMenuInfo.background_color); settings.AddInt32("separator", fMenuInfo.separator); settings.AddBool("click to open", fMenuInfo.click_to_open); - settings.AddBool("triggers always shown", fMenuInfo.triggers_always_shown); + settings.AddBool("triggers always shown", + fMenuInfo.triggers_always_shown); + + settings.AddBool("subpixel antialiasing", gSubpixelAntialiasing); + settings.AddInt8("subpixel average weight", gSubpixelAverageWeight); + settings.AddBool("subpixel ordering", gSubpixelOrderingRGB); for (int32 i = 0; i < kNumColors; i++) { char colorName[12]; @@ -352,7 +373,8 @@ DesktopSettingsPrivate::Save(uint32 mask) } BFile file; - status = file.SetTo(path.Path(), B_CREATE_FILE | B_ERASE_FILE | B_READ_WRITE); + status = file.SetTo(path.Path(), B_CREATE_FILE | B_ERASE_FILE + | B_READ_WRITE); if (status == B_OK) { status = settings.Flatten(&file, NULL); } @@ -544,39 +566,62 @@ DesktopSettingsPrivate::UIColor(color_which which) const void -DesktopSettingsPrivate::SetFontSubpixelAntialiasing(bool subpix) +DesktopSettingsPrivate::SetSubpixelAntialiasing(bool subpix) { - if (fFontSubpixelAntialiasing != subpix) { - fFontSubpixelAntialiasing = subpix; - FontCacheEntry::SetDefaultRenderType( - (subpix)?glyph_ren_subpix:glyph_ren_native_gray8); - Save(kFontSettings); - } + gSubpixelAntialiasing = subpix; + Save(kAppearanceSettings); } bool -DesktopSettingsPrivate::FontSubpixelAntialiasing() const +DesktopSettingsPrivate::SubpixelAntialiasing() const { - return fFontSubpixelAntialiasing; + return gSubpixelAntialiasing; } void DesktopSettingsPrivate::SetHinting(bool hinting) { - if (fHinting != hinting) { - fHinting = hinting; - FontCacheEntry::SetDefaultHinting(hinting); - Save(kFontSettings); - } + gDefaultHinting = hinting; + Save(kFontSettings); } bool DesktopSettingsPrivate::Hinting() const { - return fHinting; + return gDefaultHinting; +} + + +void +DesktopSettingsPrivate::SetSubpixelAverageWeight(uint8 averageWeight) +{ + gSubpixelAverageWeight = averageWeight; + Save(kAppearanceSettings); +} + + +uint8 +DesktopSettingsPrivate::SubpixelAverageWeight() const +{ + return gSubpixelAverageWeight; +} + + +void +DesktopSettingsPrivate::SetSubpixelOrderingRegular(bool subpixelOrdering) +{ + gSubpixelOrderingRGB = subpixelOrdering; + Save(kAppearanceSettings); +} + + +bool +DesktopSettingsPrivate::IsSubpixelOrderingRegular() const +{ + return gSubpixelOrderingRGB; } // #pragma mark - read access @@ -672,9 +717,9 @@ DesktopSettings::UIColor(color_which which) const bool -DesktopSettings::FontSubpixelAntialiasing() const +DesktopSettings::SubpixelAntialiasing() const { - return fSettings->FontSubpixelAntialiasing(); + return fSettings->SubpixelAntialiasing(); } @@ -684,6 +729,21 @@ DesktopSettings::Hinting() const return fSettings->Hinting(); } + +uint8 +DesktopSettings::SubpixelAverageWeight() const +{ + return fSettings->SubpixelAverageWeight(); +} + + +bool +DesktopSettings::IsSubpixelOrderingRegular() const +{ + // True corresponds to RGB, false means BGR + return fSettings->IsSubpixelOrderingRegular(); +} + // #pragma mark - write access @@ -763,9 +823,9 @@ LockedDesktopSettings::SetUIColor(color_which which, const rgb_color color) void -LockedDesktopSettings::SetFontSubpixelAntialiasing(bool subpix) +LockedDesktopSettings::SetSubpixelAntialiasing(bool subpix) { - fSettings->SetFontSubpixelAntialiasing(subpix); + fSettings->SetSubpixelAntialiasing(subpix); } @@ -775,3 +835,16 @@ LockedDesktopSettings::SetHinting(bool hinting) fSettings->SetHinting(hinting); } + +void +LockedDesktopSettings::SetSubpixelAverageWeight(uint8 averageWeight) +{ + fSettings->SetSubpixelAverageWeight(averageWeight); +} + +void +LockedDesktopSettings::SetSubpixelOrderingRegular(bool subpixelOrdering) +{ + fSettings->SetSubpixelOrderingRegular(subpixelOrdering); +} + diff --git a/src/servers/app/DesktopSettings.h b/src/servers/app/DesktopSettings.h index bb4b30e3ae..073ecd740a 100644 --- a/src/servers/app/DesktopSettings.h +++ b/src/servers/app/DesktopSettings.h @@ -53,8 +53,10 @@ class DesktopSettings { rgb_color UIColor(color_which which) const; - bool FontSubpixelAntialiasing() const; + bool SubpixelAntialiasing() const; bool Hinting() const; + uint8 SubpixelAverageWeight() const; + bool IsSubpixelOrderingRegular() const; protected: DesktopSettingsPrivate* fSettings; @@ -78,8 +80,10 @@ class LockedDesktopSettings : public DesktopSettings { void SetUIColor(color_which which, const rgb_color color); - void SetFontSubpixelAntialiasing(bool subpix); + void SetSubpixelAntialiasing(bool subpix); void SetHinting(bool hinting); + void SetSubpixelAverageWeight(uint8 averageWeight); + void SetSubpixelOrderingRegular(bool subpixelOrdering); private: Desktop* fDesktop; diff --git a/src/servers/app/DesktopSettingsPrivate.h b/src/servers/app/DesktopSettingsPrivate.h index 5d8bb180da..dfc640875e 100644 --- a/src/servers/app/DesktopSettingsPrivate.h +++ b/src/servers/app/DesktopSettingsPrivate.h @@ -56,10 +56,14 @@ class DesktopSettingsPrivate { void SetUIColor(color_which which, const rgb_color color); rgb_color UIColor(color_which which) const; - void SetFontSubpixelAntialiasing(bool subpix); - bool FontSubpixelAntialiasing() const; + void SetSubpixelAntialiasing(bool subpix); + bool SubpixelAntialiasing() const; void SetHinting(bool hinting); bool Hinting() const; + void SetSubpixelAverageWeight(uint8 averageWeight); + uint8 SubpixelAverageWeight() const; + void SetSubpixelOrderingRegular(bool SubpixelOrdering); + bool IsSubpixelOrderingRegular() const; private: void _SetDefaults(); @@ -77,9 +81,6 @@ class DesktopSettingsPrivate { int32 fWorkspacesCount; BMessage fWorkspaceMessages[kMaxWorkspaces]; - bool fFontSubpixelAntialiasing; - bool fHinting; - server_read_only_memory& fShared; }; diff --git a/src/servers/app/FontCacheEntry.cpp b/src/servers/app/FontCacheEntry.cpp index 05fe5b9f2b..e8865dcd88 100644 --- a/src/servers/app/FontCacheEntry.cpp +++ b/src/servers/app/FontCacheEntry.cpp @@ -33,16 +33,12 @@ #include "utf8_functions.h" +#include "GlobalSubpixelSettings.h" + + BLocker FontCacheEntry::sUsageUpdateLock("FontCacheEntry usage lock"); -glyph_rendering -FontCacheEntry::sDefaultRenderType; - -bool -FontCacheEntry::sDefaultHinting; - - class FontCacheEntry::GlyphCachePool { public: enum block_size_e { block_size = 16384-16 }; @@ -127,7 +123,7 @@ FontCacheEntry::Init(const ServerFont& font) // TODO: encoding from font FT_Encoding charMap = FT_ENCODING_NONE; - bool hinting = sDefaultHinting; // TODO: font.Hinting(); + bool hinting = gDefaultHinting; // TODO: font.Hinting(); if (!fEngine.Init(font.Path(), 0, font.Size(), charMap, renderingType, hinting)) { @@ -224,11 +220,12 @@ FontCacheEntry::GenerateSignature(char* signature, const ServerFont& font) // TODO: read more of these from the font FT_Encoding charMap = FT_ENCODING_NONE; - bool hinting = sDefaultHinting; // TODO: font.Hinting(); + bool hinting = gDefaultHinting; // TODO: font.Hinting(); + uint8 averageWeight = gSubpixelAverageWeight; - sprintf(signature, "%ld,%u,%d,%d,%.1f,%d", + sprintf(signature, "%ld,%u,%d,%d,%.1f,%d,%d", font.GetFamilyAndStyle(), charMap, - font.Face(), int(renderingType), font.Size(), hinting); + font.Face(), int(renderingType), font.Size(), hinting, averageWeight); } // UpdateUsage @@ -247,31 +244,20 @@ FontCacheEntry::UpdateUsage() } -void -FontCacheEntry::SetDefaultRenderType(glyph_rendering renderingType) -{ - sDefaultRenderType = renderingType; -} - - -void -FontCacheEntry::SetDefaultHinting(bool hinting) -{ - sDefaultHinting = hinting; -} - - // _RenderTypeFor /*static*/ glyph_rendering FontCacheEntry::_RenderTypeFor(const ServerFont& font) { - glyph_rendering renderingType = sDefaultRenderType; + glyph_rendering renderingType = gSubpixelAntialiasing ? + glyph_ren_subpix : glyph_ren_native_gray8; + if (font.Rotation() != 0.0 || font.Shear() != 90.0 || font.FalseBoldWidth() != 0.0 || font.Flags() & B_DISABLE_ANTIALIASING || font.Size() > 30 - || !sDefaultHinting) { + || !gDefaultHinting) { renderingType = glyph_ren_outline; } + return renderingType; } diff --git a/src/servers/app/FontCacheEntry.h b/src/servers/app/FontCacheEntry.h index 71eba77691..1d0e936148 100644 --- a/src/servers/app/FontCacheEntry.h +++ b/src/servers/app/FontCacheEntry.h @@ -94,13 +94,6 @@ class FontCacheEntry : public MultiLocker, public Referenceable { static void GenerateSignature(char* signature, const ServerFont& font); - - static void SetDefaultRenderType(glyph_rendering renderType); - static glyph_rendering DefaultRenderType() - { return sDefaultRenderType; } - static void SetDefaultHinting(bool hinting); - static bool DefaultHinting() - { return sDefaultHinting; } // private to FontCache class: void UpdateUsage(); @@ -119,8 +112,6 @@ class FontCacheEntry : public MultiLocker, public Referenceable { GlyphCachePool* fGlyphCache; FontEngine fEngine; - static glyph_rendering sDefaultRenderType; - static bool sDefaultHinting; static BLocker sUsageUpdateLock; bigtime_t fLastUsedTime; diff --git a/src/servers/app/FontEngine.cpp b/src/servers/app/FontEngine.cpp index 7d1bb2e24d..7cf4b0373f 100644 --- a/src/servers/app/FontEngine.cpp +++ b/src/servers/app/FontEngine.cpp @@ -36,7 +36,7 @@ #include #include - +#include "GlobalSubpixelSettings.h" static const bool kFlipY = true; @@ -365,21 +365,6 @@ decompose_ft_bitmap_gray8(const FT_Bitmap& bitmap, int x, int y, } -#define AVERAGE_BASED_SUBPIXEL_FILTERING -// NOTE stippi: My basic idea is that filtering tries to minimize colored -// edges, but it does so by blurring the coverage values. This will also -// affect neighboring pixels and add blur where there were perfectly sharp -// edges. Andrej's method of filtering adds a special case for perfectly -// sharp edges, but the drawback here is that there will be a visible -// transition between blurred and non-blurred subpixels. I had the idea that -// when simply fading the subpixels towards the plain gray-scale-aa values, -// there must be a sweet spot for when colored edges become non-disturbing -// and there is still a benefit of sharpness compared to straight gray-scale- -// aa. The define above enables this method against the colored edges. My -// method still has a drawback, since jaggies in diagonal lines will be more -// visible again than with the filter method. - - // decompose_ft_bitmap_subpix template void @@ -387,13 +372,6 @@ decompose_ft_bitmap_subpix(const FT_Bitmap& bitmap, int x, int y, bool flip_y, Scanline& sl, ScanlineStorage& storage) { #ifdef AVERAGE_BASED_SUBPIXEL_FILTERING - // The weight with which the average of the subpixels is applied to counter - // color fringes (0 = full sharpness ... 255 = grayscale anti-aliasing) - // TODO: This could be a config option, but don't forget to include the - // value in the font cache entry signature generation! - const uint8 averageWeight = 100; - const uint8 subpixelWeight = 255 - averageWeight; - const uint8* buf = (const uint8*)bitmap.buffer; int pitch = bitmap.pitch; sl.reset(x, x + bitmap.width / 3); @@ -420,20 +398,11 @@ decompose_ft_bitmap_subpix(const FT_Bitmap& bitmap, int x, int y, } } else { const uint8* p = buf; - uint32 coverR; - uint32 coverG; - uint32 coverB; int w = bitmap.width / 3; for (int j = 0; j < w; j++) { - uint32 average = (p[0] + p[1] + p[2] + 2) / 3; - coverR = (p[0] * subpixelWeight + average * averageWeight) >> 8; - coverG = (p[1] * subpixelWeight + average * averageWeight) >> 8; - coverB = (p[2] * subpixelWeight + average * averageWeight) >> 8; - - if (coverR || coverG || coverB) - sl.add_cell(x + j, coverR, coverG, coverB); - + if (p[0] || p[1] || p[2]) + sl.add_cell(x + j, p[0], p[1], p[2]); p += 3; } } @@ -444,7 +413,8 @@ decompose_ft_bitmap_subpix(const FT_Bitmap& bitmap, int x, int y, storage.render(sl); } } -#else // filter based anti-colored edges method +#else +// filter based anti-colored edges method // Filtering weights const uint8 filter[5] = { 0x10, 0x40, 0x70, 0x40, 0x10 }; diff --git a/src/servers/app/FontEngine.h b/src/servers/app/FontEngine.h index 497fef66fe..b0e5f7e473 100644 --- a/src/servers/app/FontEngine.h +++ b/src/servers/app/FontEngine.h @@ -42,6 +42,9 @@ #include "agg_scanline_storage_subpix.h" #include "agg_scanline_u_subpix.h" +#include "agg_scanline_u_subpix_avrg_filtering.h" + +#include "GlobalSubpixelSettings.h" enum glyph_rendering { @@ -147,7 +150,11 @@ class FontEngine { CurveConverterType fCurves; agg::scanline_u8 fScanlineAA; agg::scanline_bin fScanlineBin; +#ifdef AVERAGE_BASED_SUBPIXEL_FILTERING + agg::scanline_u8_subpix_avrg_filtering fScanlineSubpix; +#else agg::scanline_u8_subpix fScanlineSubpix; +#endif ScanlineStorageAA fScanlineStorageAA; ScanlineStorageBin fScanlineStorageBin; diff --git a/src/servers/app/ProfileMessageSupport.cpp b/src/servers/app/ProfileMessageSupport.cpp index 48253f7880..87e6699b7a 100644 --- a/src/servers/app/ProfileMessageSupport.cpp +++ b/src/servers/app/ProfileMessageSupport.cpp @@ -175,10 +175,15 @@ string_for_message_code(uint32 code, BString& string) case AS_GET_SHOW_ALL_DRAGGERS: string = "AS_GET_SHOW_ALL_DRAGGERS"; break; case AS_SET_SHOW_ALL_DRAGGERS: string = "AS_SET_SHOW_ALL_DRAGGERS"; break; - case AS_SET_FONT_SUBPIXEL_ANTIALIASING: string = "AS_SET_FONT_SUBPIXEL_ANTIALIASING"; break; - case AS_GET_FONT_SUBPIXEL_ANTIALIASING: string = "AS_GET_FONT_SUBPIXEL_ANTIALIASING"; break; + // Subpixel antialiasing & hinting + case AS_SET_SUBPIXEL_ANTIALIASING: string = "AS_SET_SUBPIXEL_ANTIALIASING"; break; + case AS_GET_SUBPIXEL_ANTIALIASING: string = "AS_GET_SUBPIXEL_ANTIALIASING"; break; case AS_SET_HINTING: string = "AS_SET_HINTING"; break; case AS_GET_HINTING: string = "AS_GET_HINTING"; break; + case AS_SET_SUBPIXEL_AVERAGE_WEIGHT: string = "AS_SET_SUBPIXEL_AVERAGE_WEIGHT"; break; + case AS_GET_SUBPIXEL_AVERAGE_WEIGHT: string = "AS_GET_SUBPIXEL_AVERAGE_WEIGHT"; break; + case AS_SET_SUBPIXEL_ORDERING: string = "AS_SET_SUBPIXEL_ORDERING"; break; + case AS_GET_SUBPIXEL_ORDERING: string = "AS_GET_SUBPIXEL_ORDERING"; break; // Graphics calls case AS_SET_HIGH_COLOR: string = "AS_SET_HIGH_COLOR"; break; diff --git a/src/servers/app/ServerApp.cpp b/src/servers/app/ServerApp.cpp index 09ca4fc6b7..bc26eb00a2 100644 --- a/src/servers/app/ServerApp.cpp +++ b/src/servers/app/ServerApp.cpp @@ -2537,22 +2537,22 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) break; } - case AS_SET_FONT_SUBPIXEL_ANTIALIASING: + case AS_SET_SUBPIXEL_ANTIALIASING: { bool subpix; if (link.Read(&subpix) == B_OK) { LockedDesktopSettings settings(fDesktop); - settings.SetFontSubpixelAntialiasing(subpix); + settings.SetSubpixelAntialiasing(subpix); } fDesktop->Redraw(); break; } - case AS_GET_FONT_SUBPIXEL_ANTIALIASING: + case AS_GET_SUBPIXEL_ANTIALIASING: { DesktopSettings settings(fDesktop); fLink.StartMessage(B_OK); - fLink.Attach(settings.FontSubpixelAntialiasing()); + fLink.Attach(settings.SubpixelAntialiasing()); fLink.Flush(); break; } @@ -2576,6 +2576,46 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) fLink.Flush(); break; } + + case AS_SET_SUBPIXEL_AVERAGE_WEIGHT: + { + uint8 averageWeight; + if (link.Read(&averageWeight) == B_OK) { + LockedDesktopSettings settings(fDesktop); + settings.SetSubpixelAverageWeight(averageWeight); + } + fDesktop->Redraw(); + break; + } + + case AS_GET_SUBPIXEL_AVERAGE_WEIGHT: + { + DesktopSettings settings(fDesktop); + fLink.StartMessage(B_OK); + fLink.Attach(settings.SubpixelAverageWeight()); + fLink.Flush(); + break; + } + + case AS_SET_SUBPIXEL_ORDERING: + { + bool subpixelOrdering; + if (link.Read(&subpixelOrdering) == B_OK) { + LockedDesktopSettings settings(fDesktop); + settings.SetSubpixelOrderingRegular(subpixelOrdering); + } + fDesktop->Redraw(); + break; + } + + case AS_GET_SUBPIXEL_ORDERING: + { + DesktopSettings settings(fDesktop); + fLink.StartMessage(B_OK); + fLink.Attach(settings.IsSubpixelOrderingRegular()); + fLink.Flush(); + break; + } default: printf("ServerApp %s received unhandled message code %ld\n", diff --git a/src/servers/app/agg_scanline_storage_subpix.h b/src/servers/app/agg_scanline_storage_subpix.h index 24db6d3f71..2df7fe2a84 100644 --- a/src/servers/app/agg_scanline_storage_subpix.h +++ b/src/servers/app/agg_scanline_storage_subpix.h @@ -22,658 +22,658 @@ namespace agg { - //--------------------------------------------scanline_storage_subpix - template class scanline_storage_subpix - { - public: - typedef T cover_type; - - //--------------------------------------------------------------- - struct span_data - { - int32 x; - int32 len; // If negative, it's a solid span, covers is valid - int covers_id; // The index of the cells in the scanline_cell_storage - }; - - //--------------------------------------------------------------- - struct scanline_data - { - int y; - unsigned num_spans; - unsigned start_span; - }; - - - //--------------------------------------------------------------- - class embedded_scanline - { - public: - - //----------------------------------------------------------- - class const_iterator - { - public: - struct span - { - int32 x; - int32 len; // If negative, it's a solid span, covers is valid - const T* covers; - }; - - const_iterator() : m_storage(0) {} - const_iterator(const embedded_scanline& sl) : - m_storage(sl.m_storage), - m_span_idx(sl.m_scanline.start_span) - { - init_span(); - } - - const span& operator*() const { return m_span; } - const span* operator->() const { return &m_span; } - - void operator ++ () - { - ++m_span_idx; - init_span(); - } - - private: - void init_span() - { - const span_data& s = m_storage->span_by_index(m_span_idx); - m_span.x = s.x; - m_span.len = s.len; - m_span.covers = m_storage->covers_by_index(s.covers_id); - } - - const scanline_storage_subpix* m_storage; - unsigned m_span_idx; - span m_span; - }; - - friend class const_iterator; - - - //----------------------------------------------------------- - embedded_scanline(const scanline_storage_subpix& storage) : - m_storage(&storage) - { - init(0); - } - - //----------------------------------------------------------- - void reset(int, int) {} - unsigned num_spans() const { return m_scanline.num_spans; } - int y() const { return m_scanline.y; } - const_iterator begin() const { return const_iterator(*this); } - - //----------------------------------------------------------- - void init(unsigned scanline_idx) - { - m_scanline_idx = scanline_idx; - m_scanline = m_storage->scanline_by_index(m_scanline_idx); - } - - private: - const scanline_storage_subpix* m_storage; - scanline_data m_scanline; - unsigned m_scanline_idx; - }; - - - //--------------------------------------------------------------- - scanline_storage_subpix() : - m_covers(), - m_spans(256-2), // Block increment size - m_scanlines(), - m_min_x( 0x7FFFFFFF), - m_min_y( 0x7FFFFFFF), - m_max_x(-0x7FFFFFFF), - m_max_y(-0x7FFFFFFF), - m_cur_scanline(0) - { - m_fake_scanline.y = 0; - m_fake_scanline.num_spans = 0; - m_fake_scanline.start_span = 0; - m_fake_span.x = 0; - m_fake_span.len = 0; - m_fake_span.covers_id = 0; - } - - // Renderer Interface - //--------------------------------------------------------------- - void prepare() - { - m_covers.remove_all(); - m_scanlines.remove_all(); - m_spans.remove_all(); - m_min_x = 0x7FFFFFFF; - m_min_y = 0x7FFFFFFF; - m_max_x = -0x7FFFFFFF; - m_max_y = -0x7FFFFFFF; - m_cur_scanline = 0; - } - - //--------------------------------------------------------------- - template void render(const Scanline& sl) - { - scanline_data sl_this; - - int y = sl.y(); - if(y < m_min_y) m_min_y = y; - if(y > m_max_y) m_max_y = y; - - sl_this.y = y; - sl_this.num_spans = sl.num_spans(); - sl_this.start_span = m_spans.size(); - typename Scanline::const_iterator span_iterator = sl.begin(); - - unsigned num_spans = sl_this.num_spans; - for(;;) - { - span_data sp; - - sp.x = span_iterator->x; - sp.len = span_iterator->len; - int len = abs(int(sp.len)); - sp.covers_id = - m_covers.add_cells(span_iterator->covers, - (unsigned(len))); - m_spans.add(sp); - int x1 = sp.x; - int x2 = sp.x + len/3 - 1; - if(x1 < m_min_x) m_min_x = x1; - if(x2 > m_max_x) m_max_x = x2; - if(--num_spans == 0) break; - ++span_iterator; - } - m_scanlines.add(sl_this); - } - - - //--------------------------------------------------------------- - // Iterate scanlines interface - int min_x() const { return m_min_x; } - int min_y() const { return m_min_y; } - int max_x() const { return m_max_x; } - int max_y() const { return m_max_y; } - - //--------------------------------------------------------------- - bool rewind_scanlines() - { - m_cur_scanline = 0; - return m_scanlines.size() > 0; - } - - - //--------------------------------------------------------------- - template bool sweep_scanline(Scanline& sl) - { - sl.reset_spans(); - for(;;) - { - if(m_cur_scanline >= m_scanlines.size()) return false; - const scanline_data& sl_this = m_scanlines[m_cur_scanline]; - - unsigned num_spans = sl_this.num_spans; - unsigned span_idx = sl_this.start_span; - do - { - const span_data& sp = m_spans[span_idx++]; - const T* covers = covers_by_index(sp.covers_id); - if(sp.len < 0) - { - sl.add_span(sp.x, unsigned(-sp.len), *covers); - } - else - { - sl.add_cells(sp.x, sp.len, covers); - } - } - while(--num_spans); - ++m_cur_scanline; - if(sl.num_spans()) - { - sl.finalize(sl_this.y); - break; - } - } - return true; - } - - - //--------------------------------------------------------------- - // Specialization for embedded_scanline - bool sweep_scanline(embedded_scanline& sl) - { - do - { - if(m_cur_scanline >= m_scanlines.size()) return false; - sl.init(m_cur_scanline); - ++m_cur_scanline; - } - while(sl.num_spans() == 0); - return true; - } - - //--------------------------------------------------------------- - unsigned byte_size() const - { - unsigned i; - unsigned size = sizeof(int32) * 4; // min_x, min_y, max_x, max_y - - for(i = 0; i < m_scanlines.size(); ++i) - { - size += sizeof(int32) * 3; // scanline size in bytes - - const scanline_data& sl_this = m_scanlines[i]; - - unsigned num_spans = sl_this.num_spans; - unsigned span_idx = sl_this.start_span; - do - { - const span_data& sp = m_spans[span_idx++]; - - size += sizeof(int32) * 2; // X, span_len - if(sp.len < 0) - { - size += sizeof(T); // cover - } - else - { - size += sizeof(T) * unsigned(sp.len); // covers - } - } - while(--num_spans); - } - return size; - } - - - //--------------------------------------------------------------- - static void write_int32(int8u* dst, int32 val) - { - dst[0] = ((const int8u*)&val)[0]; - dst[1] = ((const int8u*)&val)[1]; - dst[2] = ((const int8u*)&val)[2]; - dst[3] = ((const int8u*)&val)[3]; - } - - - //--------------------------------------------------------------- - void serialize(int8u* data) const - { - unsigned i; - - write_int32(data, min_x()); // min_x - data += sizeof(int32); - write_int32(data, min_y()); // min_y - data += sizeof(int32); - write_int32(data, max_x()); // max_x - data += sizeof(int32); - write_int32(data, max_y()); // max_y - data += sizeof(int32); - - for(i = 0; i < m_scanlines.size(); ++i) - { - const scanline_data& sl_this = m_scanlines[i]; - - int8u* size_ptr = data; - data += sizeof(int32); // Reserve space for scanline size in bytes - - write_int32(data, sl_this.y); // Y - data += sizeof(int32); - - write_int32(data, sl_this.num_spans); // num_spans - data += sizeof(int32); - - unsigned num_spans = sl_this.num_spans; - unsigned span_idx = sl_this.start_span; - do - { - const span_data& sp = m_spans[span_idx++]; - const T* covers = covers_by_index(sp.covers_id); - - write_int32(data, sp.x); // X - data += sizeof(int32); - - write_int32(data, sp.len); // span_len - data += sizeof(int32); - - if(sp.len < 0) - { - memcpy(data, covers, sizeof(T)); - data += sizeof(T); - } - else - { - memcpy(data, covers, unsigned(sp.len) * sizeof(T)); - data += sizeof(T) * unsigned(sp.len); - } - } - while(--num_spans); - write_int32(size_ptr, int32(unsigned(data - size_ptr))); - } - } - - - //--------------------------------------------------------------- - const scanline_data& scanline_by_index(unsigned i) const - { - return (i < m_scanlines.size()) ? m_scanlines[i] : m_fake_scanline; - } - - //--------------------------------------------------------------- - const span_data& span_by_index(unsigned i) const - { - return (i < m_spans.size()) ? m_spans[i] : m_fake_span; - } - - //--------------------------------------------------------------- - const T* covers_by_index(int i) const - { - return m_covers[i]; - } - - private: - scanline_cell_storage m_covers; - pod_bvector m_spans; - pod_bvector m_scanlines; - span_data m_fake_span; - scanline_data m_fake_scanline; - int m_min_x; - int m_min_y; - int m_max_x; - int m_max_y; - unsigned m_cur_scanline; - }; - - - typedef scanline_storage_subpix scanline_storage_subpix8; //--------scanline_storage_subpix8 - typedef scanline_storage_subpix scanline_storage_subpix16; //--------scanline_storage_subpix16 - typedef scanline_storage_subpix scanline_storage_subpix32; //--------scanline_storage_subpix32 - - - //--------------------------------------serialized_scanlines_adaptor_subpix - template class serialized_scanlines_adaptor_subpix - { - public: - typedef T cover_type; - - //--------------------------------------------------------------------- - class embedded_scanline - { - public: - typedef T cover_type; - - //----------------------------------------------------------------- - class const_iterator - { - public: - struct span - { - int32 x; - int32 len; // If negative, it's a solid span, "covers" is valid - const T* covers; - }; - - const_iterator() : m_ptr(0) {} - const_iterator(const embedded_scanline& sl) : - m_ptr(sl.m_ptr), - m_dx(sl.m_dx) - { - init_span(); - } - - const span& operator*() const { return m_span; } - const span* operator->() const { return &m_span; } - - void operator ++ () - { - if(m_span.len < 0) - { - m_ptr += sizeof(T); - } - else - { - m_ptr += m_span.len * sizeof(T); - } - init_span(); - } - - private: - int read_int32() - { - int32 val; - ((int8u*)&val)[0] = *m_ptr++; - ((int8u*)&val)[1] = *m_ptr++; - ((int8u*)&val)[2] = *m_ptr++; - ((int8u*)&val)[3] = *m_ptr++; - return val; - } - - void init_span() - { - m_span.x = read_int32() + m_dx; - m_span.len = read_int32(); - m_span.covers = m_ptr; - } - - const int8u* m_ptr; - span m_span; - int m_dx; - }; - - friend class const_iterator; - - - //----------------------------------------------------------------- - embedded_scanline() : m_ptr(0), m_y(0), m_num_spans(0) {} - - //----------------------------------------------------------------- - void reset(int, int) {} - unsigned num_spans() const { return m_num_spans; } - int y() const { return m_y; } - const_iterator begin() const { return const_iterator(*this); } - - - private: - //----------------------------------------------------------------- - int read_int32() - { - int32 val; - ((int8u*)&val)[0] = *m_ptr++; - ((int8u*)&val)[1] = *m_ptr++; - ((int8u*)&val)[2] = *m_ptr++; - ((int8u*)&val)[3] = *m_ptr++; - return val; - } - - public: - //----------------------------------------------------------------- - void init(const int8u* ptr, int dx, int dy) - { - m_ptr = ptr; - m_y = read_int32() + dy; - m_num_spans = unsigned(read_int32()); - m_dx = dx; - } - - private: - const int8u* m_ptr; - int m_y; - unsigned m_num_spans; - int m_dx; - }; - - - - public: - //-------------------------------------------------------------------- - serialized_scanlines_adaptor_subpix() : - m_data(0), - m_end(0), - m_ptr(0), - m_dx(0), - m_dy(0), - m_min_x(0x7FFFFFFF), - m_min_y(0x7FFFFFFF), - m_max_x(-0x7FFFFFFF), - m_max_y(-0x7FFFFFFF) - {} - - //-------------------------------------------------------------------- - serialized_scanlines_adaptor_subpix(const int8u* data, unsigned size, - double dx, double dy) : - m_data(data), - m_end(data + size), - m_ptr(data), - m_dx(iround(dx)), - m_dy(iround(dy)), - m_min_x(0x7FFFFFFF), - m_min_y(0x7FFFFFFF), - m_max_x(-0x7FFFFFFF), - m_max_y(-0x7FFFFFFF) - {} - - //-------------------------------------------------------------------- - void init(const int8u* data, unsigned size, double dx, double dy) - { - m_data = data; - m_end = data + size; - m_ptr = data; - m_dx = iround(dx); - m_dy = iround(dy); - m_min_x = 0x7FFFFFFF; - m_min_y = 0x7FFFFFFF; - m_max_x = -0x7FFFFFFF; - m_max_y = -0x7FFFFFFF; - } - - private: - //-------------------------------------------------------------------- - int read_int32() - { - int32 val; - ((int8u*)&val)[0] = *m_ptr++; - ((int8u*)&val)[1] = *m_ptr++; - ((int8u*)&val)[2] = *m_ptr++; - ((int8u*)&val)[3] = *m_ptr++; - return val; - } - - //-------------------------------------------------------------------- - unsigned read_int32u() - { - int32u val; - ((int8u*)&val)[0] = *m_ptr++; - ((int8u*)&val)[1] = *m_ptr++; - ((int8u*)&val)[2] = *m_ptr++; - ((int8u*)&val)[3] = *m_ptr++; - return val; - } - - public: - // Iterate scanlines interface - //-------------------------------------------------------------------- - bool rewind_scanlines() - { - m_ptr = m_data; - if(m_ptr < m_end) - { - m_min_x = read_int32() + m_dx; - m_min_y = read_int32() + m_dy; - m_max_x = read_int32() + m_dx; - m_max_y = read_int32() + m_dy; - } - return m_ptr < m_end; - } - - //-------------------------------------------------------------------- - int min_x() const { return m_min_x; } - int min_y() const { return m_min_y; } - int max_x() const { return m_max_x; } - int max_y() const { return m_max_y; } - - //-------------------------------------------------------------------- - template bool sweep_scanline(Scanline& sl) - { - sl.reset_spans(); - for(;;) - { - if(m_ptr >= m_end) return false; - - read_int32(); // Skip scanline size in bytes - int y = read_int32() + m_dy; - unsigned num_spans = read_int32(); - - do - { - int x = read_int32() + m_dx; - int len = read_int32(); - - if(len < 0) - { - sl.add_span(x, unsigned(-len), *m_ptr); - m_ptr += sizeof(T); - } - else - { - sl.add_cells(x, len, m_ptr); - m_ptr += len * sizeof(T); - } - } - while(--num_spans); - - if(sl.num_spans()) - { - sl.finalize(y); - break; - } - } - return true; - } - - - //-------------------------------------------------------------------- - // Specialization for embedded_scanline - bool sweep_scanline(embedded_scanline& sl) - { - do - { - if(m_ptr >= m_end) return false; - - unsigned byte_size = read_int32u(); - sl.init(m_ptr, m_dx, m_dy); - m_ptr += byte_size - sizeof(int32); - } - while(sl.num_spans() == 0); - return true; - } - - private: - const int8u* m_data; - const int8u* m_end; - const int8u* m_ptr; - int m_dx; - int m_dy; - int m_min_x; - int m_min_y; - int m_max_x; - int m_max_y; - }; - - - - typedef serialized_scanlines_adaptor_subpix - serialized_scanlines_adaptor_subpix8; //serialized_scanlines_adaptor_subpix8 - - typedef serialized_scanlines_adaptor_subpix - serialized_scanlines_adaptor_subpix16; //serialized_scanlines_adaptor_subpix16 - - typedef serialized_scanlines_adaptor_subpix - serialized_scanlines_adaptor_subpix32; //serialized_scanlines_adaptor_subpix32 + //--------------------------------------------scanline_storage_subpix + template class scanline_storage_subpix + { + public: + typedef T cover_type; + + //--------------------------------------------------------------- + struct span_data + { + int32 x; + int32 len; // If negative, it's a solid span, covers is valid + int covers_id; // The index of the cells in the scanline_cell_storage + }; + + //--------------------------------------------------------------- + struct scanline_data + { + int y; + unsigned num_spans; + unsigned start_span; + }; + + + //--------------------------------------------------------------- + class embedded_scanline + { + public: + + //----------------------------------------------------------- + class const_iterator + { + public: + struct span + { + int32 x; + int32 len; // If negative, it's a solid span, covers is valid + const T* covers; + }; + + const_iterator() : m_storage(0) {} + const_iterator(const embedded_scanline& sl) : + m_storage(sl.m_storage), + m_span_idx(sl.m_scanline.start_span) + { + init_span(); + } + + const span& operator*() const { return m_span; } + const span* operator->() const { return &m_span; } + + void operator ++ () + { + ++m_span_idx; + init_span(); + } + + private: + void init_span() + { + const span_data& s = m_storage->span_by_index(m_span_idx); + m_span.x = s.x; + m_span.len = s.len; + m_span.covers = m_storage->covers_by_index(s.covers_id); + } + + const scanline_storage_subpix* m_storage; + unsigned m_span_idx; + span m_span; + }; + + friend class const_iterator; + + + //----------------------------------------------------------- + embedded_scanline(const scanline_storage_subpix& storage) : + m_storage(&storage) + { + init(0); + } + + //----------------------------------------------------------- + void reset(int, int) {} + unsigned num_spans() const { return m_scanline.num_spans; } + int y() const { return m_scanline.y; } + const_iterator begin() const { return const_iterator(*this); } + + //----------------------------------------------------------- + void init(unsigned scanline_idx) + { + m_scanline_idx = scanline_idx; + m_scanline = m_storage->scanline_by_index(m_scanline_idx); + } + + private: + const scanline_storage_subpix* m_storage; + scanline_data m_scanline; + unsigned m_scanline_idx; + }; + + + //--------------------------------------------------------------- + scanline_storage_subpix() : + m_covers(), + m_spans(256-2), // Block increment size + m_scanlines(), + m_min_x( 0x7FFFFFFF), + m_min_y( 0x7FFFFFFF), + m_max_x(-0x7FFFFFFF), + m_max_y(-0x7FFFFFFF), + m_cur_scanline(0) + { + m_fake_scanline.y = 0; + m_fake_scanline.num_spans = 0; + m_fake_scanline.start_span = 0; + m_fake_span.x = 0; + m_fake_span.len = 0; + m_fake_span.covers_id = 0; + } + + // Renderer Interface + //--------------------------------------------------------------- + void prepare() + { + m_covers.remove_all(); + m_scanlines.remove_all(); + m_spans.remove_all(); + m_min_x = 0x7FFFFFFF; + m_min_y = 0x7FFFFFFF; + m_max_x = -0x7FFFFFFF; + m_max_y = -0x7FFFFFFF; + m_cur_scanline = 0; + } + + //--------------------------------------------------------------- + template void render(const Scanline& sl) + { + scanline_data sl_this; + + int y = sl.y(); + if(y < m_min_y) m_min_y = y; + if(y > m_max_y) m_max_y = y; + + sl_this.y = y; + sl_this.num_spans = sl.num_spans(); + sl_this.start_span = m_spans.size(); + typename Scanline::const_iterator span_iterator = sl.begin(); + + unsigned num_spans = sl_this.num_spans; + for(;;) + { + span_data sp; + + sp.x = span_iterator->x; + sp.len = span_iterator->len; + int len = abs(int(sp.len)); + sp.covers_id = + m_covers.add_cells(span_iterator->covers, + (unsigned(len))); + m_spans.add(sp); + int x1 = sp.x; + int x2 = sp.x + len/3 - 1; + if(x1 < m_min_x) m_min_x = x1; + if(x2 > m_max_x) m_max_x = x2; + if(--num_spans == 0) break; + ++span_iterator; + } + m_scanlines.add(sl_this); + } + + + //--------------------------------------------------------------- + // Iterate scanlines interface + int min_x() const { return m_min_x; } + int min_y() const { return m_min_y; } + int max_x() const { return m_max_x; } + int max_y() const { return m_max_y; } + + //--------------------------------------------------------------- + bool rewind_scanlines() + { + m_cur_scanline = 0; + return m_scanlines.size() > 0; + } + + + //--------------------------------------------------------------- + template bool sweep_scanline(Scanline& sl) + { + sl.reset_spans(); + for(;;) + { + if(m_cur_scanline >= m_scanlines.size()) return false; + const scanline_data& sl_this = m_scanlines[m_cur_scanline]; + + unsigned num_spans = sl_this.num_spans; + unsigned span_idx = sl_this.start_span; + do + { + const span_data& sp = m_spans[span_idx++]; + const T* covers = covers_by_index(sp.covers_id); + if(sp.len < 0) + { + sl.add_span(sp.x, unsigned(-sp.len), *covers); + } + else + { + sl.add_cells(sp.x, sp.len, covers); + } + } + while(--num_spans); + ++m_cur_scanline; + if(sl.num_spans()) + { + sl.finalize(sl_this.y); + break; + } + } + return true; + } + + + //--------------------------------------------------------------- + // Specialization for embedded_scanline + bool sweep_scanline(embedded_scanline& sl) + { + do + { + if(m_cur_scanline >= m_scanlines.size()) return false; + sl.init(m_cur_scanline); + ++m_cur_scanline; + } + while(sl.num_spans() == 0); + return true; + } + + //--------------------------------------------------------------- + unsigned byte_size() const + { + unsigned i; + unsigned size = sizeof(int32) * 4; // min_x, min_y, max_x, max_y + + for(i = 0; i < m_scanlines.size(); ++i) + { + size += sizeof(int32) * 3; // scanline size in bytes + + const scanline_data& sl_this = m_scanlines[i]; + + unsigned num_spans = sl_this.num_spans; + unsigned span_idx = sl_this.start_span; + do + { + const span_data& sp = m_spans[span_idx++]; + + size += sizeof(int32) * 2; // X, span_len + if(sp.len < 0) + { + size += sizeof(T); // cover + } + else + { + size += sizeof(T) * unsigned(sp.len); // covers + } + } + while(--num_spans); + } + return size; + } + + + //--------------------------------------------------------------- + static void write_int32(int8u* dst, int32 val) + { + dst[0] = ((const int8u*)&val)[0]; + dst[1] = ((const int8u*)&val)[1]; + dst[2] = ((const int8u*)&val)[2]; + dst[3] = ((const int8u*)&val)[3]; + } + + + //--------------------------------------------------------------- + void serialize(int8u* data) const + { + unsigned i; + + write_int32(data, min_x()); // min_x + data += sizeof(int32); + write_int32(data, min_y()); // min_y + data += sizeof(int32); + write_int32(data, max_x()); // max_x + data += sizeof(int32); + write_int32(data, max_y()); // max_y + data += sizeof(int32); + + for(i = 0; i < m_scanlines.size(); ++i) + { + const scanline_data& sl_this = m_scanlines[i]; + + int8u* size_ptr = data; + data += sizeof(int32); // Reserve space for scanline size in bytes + + write_int32(data, sl_this.y); // Y + data += sizeof(int32); + + write_int32(data, sl_this.num_spans); // num_spans + data += sizeof(int32); + + unsigned num_spans = sl_this.num_spans; + unsigned span_idx = sl_this.start_span; + do + { + const span_data& sp = m_spans[span_idx++]; + const T* covers = covers_by_index(sp.covers_id); + + write_int32(data, sp.x); // X + data += sizeof(int32); + + write_int32(data, sp.len); // span_len + data += sizeof(int32); + + if(sp.len < 0) + { + memcpy(data, covers, sizeof(T)); + data += sizeof(T); + } + else + { + memcpy(data, covers, unsigned(sp.len) * sizeof(T)); + data += sizeof(T) * unsigned(sp.len); + } + } + while(--num_spans); + write_int32(size_ptr, int32(unsigned(data - size_ptr))); + } + } + + + //--------------------------------------------------------------- + const scanline_data& scanline_by_index(unsigned i) const + { + return (i < m_scanlines.size()) ? m_scanlines[i] : m_fake_scanline; + } + + //--------------------------------------------------------------- + const span_data& span_by_index(unsigned i) const + { + return (i < m_spans.size()) ? m_spans[i] : m_fake_span; + } + + //--------------------------------------------------------------- + const T* covers_by_index(int i) const + { + return m_covers[i]; + } + + private: + scanline_cell_storage m_covers; + pod_bvector m_spans; + pod_bvector m_scanlines; + span_data m_fake_span; + scanline_data m_fake_scanline; + int m_min_x; + int m_min_y; + int m_max_x; + int m_max_y; + unsigned m_cur_scanline; + }; + + + typedef scanline_storage_subpix scanline_storage_subpix8; //--------scanline_storage_subpix8 + typedef scanline_storage_subpix scanline_storage_subpix16; //--------scanline_storage_subpix16 + typedef scanline_storage_subpix scanline_storage_subpix32; //--------scanline_storage_subpix32 + + + //--------------------------------------serialized_scanlines_adaptor_subpix + template class serialized_scanlines_adaptor_subpix + { + public: + typedef T cover_type; + + //--------------------------------------------------------------------- + class embedded_scanline + { + public: + typedef T cover_type; + + //----------------------------------------------------------------- + class const_iterator + { + public: + struct span + { + int32 x; + int32 len; // If negative, it's a solid span, "covers" is valid + const T* covers; + }; + + const_iterator() : m_ptr(0) {} + const_iterator(const embedded_scanline& sl) : + m_ptr(sl.m_ptr), + m_dx(sl.m_dx) + { + init_span(); + } + + const span& operator*() const { return m_span; } + const span* operator->() const { return &m_span; } + + void operator ++ () + { + if(m_span.len < 0) + { + m_ptr += sizeof(T); + } + else + { + m_ptr += m_span.len * sizeof(T); + } + init_span(); + } + + private: + int read_int32() + { + int32 val; + ((int8u*)&val)[0] = *m_ptr++; + ((int8u*)&val)[1] = *m_ptr++; + ((int8u*)&val)[2] = *m_ptr++; + ((int8u*)&val)[3] = *m_ptr++; + return val; + } + + void init_span() + { + m_span.x = read_int32() + m_dx; + m_span.len = read_int32(); + m_span.covers = m_ptr; + } + + const int8u* m_ptr; + span m_span; + int m_dx; + }; + + friend class const_iterator; + + + //----------------------------------------------------------------- + embedded_scanline() : m_ptr(0), m_y(0), m_num_spans(0) {} + + //----------------------------------------------------------------- + void reset(int, int) {} + unsigned num_spans() const { return m_num_spans; } + int y() const { return m_y; } + const_iterator begin() const { return const_iterator(*this); } + + + private: + //----------------------------------------------------------------- + int read_int32() + { + int32 val; + ((int8u*)&val)[0] = *m_ptr++; + ((int8u*)&val)[1] = *m_ptr++; + ((int8u*)&val)[2] = *m_ptr++; + ((int8u*)&val)[3] = *m_ptr++; + return val; + } + + public: + //----------------------------------------------------------------- + void init(const int8u* ptr, int dx, int dy) + { + m_ptr = ptr; + m_y = read_int32() + dy; + m_num_spans = unsigned(read_int32()); + m_dx = dx; + } + + private: + const int8u* m_ptr; + int m_y; + unsigned m_num_spans; + int m_dx; + }; + + + + public: + //-------------------------------------------------------------------- + serialized_scanlines_adaptor_subpix() : + m_data(0), + m_end(0), + m_ptr(0), + m_dx(0), + m_dy(0), + m_min_x(0x7FFFFFFF), + m_min_y(0x7FFFFFFF), + m_max_x(-0x7FFFFFFF), + m_max_y(-0x7FFFFFFF) + {} + + //-------------------------------------------------------------------- + serialized_scanlines_adaptor_subpix(const int8u* data, unsigned size, + double dx, double dy) : + m_data(data), + m_end(data + size), + m_ptr(data), + m_dx(iround(dx)), + m_dy(iround(dy)), + m_min_x(0x7FFFFFFF), + m_min_y(0x7FFFFFFF), + m_max_x(-0x7FFFFFFF), + m_max_y(-0x7FFFFFFF) + {} + + //-------------------------------------------------------------------- + void init(const int8u* data, unsigned size, double dx, double dy) + { + m_data = data; + m_end = data + size; + m_ptr = data; + m_dx = iround(dx); + m_dy = iround(dy); + m_min_x = 0x7FFFFFFF; + m_min_y = 0x7FFFFFFF; + m_max_x = -0x7FFFFFFF; + m_max_y = -0x7FFFFFFF; + } + + private: + //-------------------------------------------------------------------- + int read_int32() + { + int32 val; + ((int8u*)&val)[0] = *m_ptr++; + ((int8u*)&val)[1] = *m_ptr++; + ((int8u*)&val)[2] = *m_ptr++; + ((int8u*)&val)[3] = *m_ptr++; + return val; + } + + //-------------------------------------------------------------------- + unsigned read_int32u() + { + int32u val; + ((int8u*)&val)[0] = *m_ptr++; + ((int8u*)&val)[1] = *m_ptr++; + ((int8u*)&val)[2] = *m_ptr++; + ((int8u*)&val)[3] = *m_ptr++; + return val; + } + + public: + // Iterate scanlines interface + //-------------------------------------------------------------------- + bool rewind_scanlines() + { + m_ptr = m_data; + if(m_ptr < m_end) + { + m_min_x = read_int32() + m_dx; + m_min_y = read_int32() + m_dy; + m_max_x = read_int32() + m_dx; + m_max_y = read_int32() + m_dy; + } + return m_ptr < m_end; + } + + //-------------------------------------------------------------------- + int min_x() const { return m_min_x; } + int min_y() const { return m_min_y; } + int max_x() const { return m_max_x; } + int max_y() const { return m_max_y; } + + //-------------------------------------------------------------------- + template bool sweep_scanline(Scanline& sl) + { + sl.reset_spans(); + for(;;) + { + if(m_ptr >= m_end) return false; + + read_int32(); // Skip scanline size in bytes + int y = read_int32() + m_dy; + unsigned num_spans = read_int32(); + + do + { + int x = read_int32() + m_dx; + int len = read_int32(); + + if(len < 0) + { + sl.add_span(x, unsigned(-len), *m_ptr); + m_ptr += sizeof(T); + } + else + { + sl.add_cells(x, len, m_ptr); + m_ptr += len * sizeof(T); + } + } + while(--num_spans); + + if(sl.num_spans()) + { + sl.finalize(y); + break; + } + } + return true; + } + + + //-------------------------------------------------------------------- + // Specialization for embedded_scanline + bool sweep_scanline(embedded_scanline& sl) + { + do + { + if(m_ptr >= m_end) return false; + + unsigned byte_size = read_int32u(); + sl.init(m_ptr, m_dx, m_dy); + m_ptr += byte_size - sizeof(int32); + } + while(sl.num_spans() == 0); + return true; + } + + private: + const int8u* m_data; + const int8u* m_end; + const int8u* m_ptr; + int m_dx; + int m_dy; + int m_min_x; + int m_min_y; + int m_max_x; + int m_max_y; + }; + + + + typedef serialized_scanlines_adaptor_subpix + serialized_scanlines_adaptor_subpix8; //serialized_scanlines_adaptor_subpix8 + + typedef serialized_scanlines_adaptor_subpix + serialized_scanlines_adaptor_subpix16; //serialized_scanlines_adaptor_subpix16 + + typedef serialized_scanlines_adaptor_subpix + serialized_scanlines_adaptor_subpix32; //serialized_scanlines_adaptor_subpix32 } diff --git a/src/servers/app/agg_scanline_u_subpix.h b/src/servers/app/agg_scanline_u_subpix.h index d0dbeaa64f..c901910862 100644 --- a/src/servers/app/agg_scanline_u_subpix.h +++ b/src/servers/app/agg_scanline_u_subpix.h @@ -17,99 +17,118 @@ namespace agg { - //======================================================scanline_u8_subpix - //------------------------------------------------------------------------ - class scanline_u8_subpix - { - public: - typedef scanline_u8_subpix self_type; - typedef int8u cover_type; - typedef int16 coord_type; + //======================================================scanline_u8_subpix + //------------------------------------------------------------------------ + class scanline_u8_subpix + { + public: + typedef scanline_u8_subpix self_type; + typedef int8u cover_type; + typedef int16 coord_type; - //-------------------------------------------------------------------- - struct span - { - coord_type x; - coord_type len; - cover_type* covers; - }; + //-------------------------------------------------------------------- + struct span + { + coord_type x; + coord_type len; + cover_type* covers; + }; - typedef span* iterator; - typedef const span* const_iterator; + typedef span* iterator; + typedef const span* const_iterator; - //-------------------------------------------------------------------- - scanline_u8_subpix() : - m_min_x(0), - m_last_x(0x7FFFFFF0), - m_cur_span(0) - {} + //-------------------------------------------------------------------- + scanline_u8_subpix() : + m_min_x(0), + m_last_x(0x7FFFFFF0), + m_cur_span(0) + {} - //-------------------------------------------------------------------- - void reset(int min_x, int max_x) - { - unsigned max_len = 3*(max_x - min_x + 2); - if(max_len > m_spans.size()) - { - m_spans.resize(max_len); - m_covers.resize(max_len); - } - m_last_x = 0x7FFFFFF0; - m_min_x = min_x; - m_cur_span = &m_spans[0]; - } + //-------------------------------------------------------------------- + void reset(int min_x, int max_x) + { + unsigned max_len = 3*(max_x - min_x + 2); + if(max_len > m_spans.size()) + { + m_spans.resize(max_len); + m_covers.resize(max_len); + } + m_last_x = 0x7FFFFFF0; + m_min_x = min_x; + m_cur_span = &m_spans[0]; + } - //-------------------------------------------------------------------- - void add_cell(int x, unsigned cover1, unsigned cover2, unsigned cover3) - { - x -= m_min_x; - m_covers[3*x] = (cover_type)cover1; - m_covers[3*x+1] = (cover_type)cover2; - m_covers[3*x+2] = (cover_type)cover3; - if(x == m_last_x+1) - { - m_cur_span->len += 3; - } - else - { - m_cur_span++; - m_cur_span->x = (coord_type)(x + m_min_x); - m_cur_span->len = 3; - m_cur_span->covers = &m_covers[3*x]; - } - m_last_x = x; - } + //-------------------------------------------------------------------- + void add_cell(int x, unsigned cover1, unsigned cover2, unsigned cover3) + { + x -= m_min_x; + m_covers[3 * x] = (cover_type)cover1; + m_covers[3 * x + 1] = (cover_type)cover2; + m_covers[3 * x + 2] = (cover_type)cover3; + if(x == m_last_x + 1) + { + m_cur_span->len += 3; + } + else + { + m_cur_span++; + m_cur_span->x = (coord_type)(x + m_min_x); + m_cur_span->len = 3; + m_cur_span->covers = &m_covers[3 * x]; + } + m_last_x = x; + } - //-------------------------------------------------------------------- - void finalize(int y) - { - m_y = y; - } + //-------------------------------------------------------------------- + void add_span(int x, unsigned len, unsigned cover) + { + x -= m_min_x; + memset(&m_covers[3 * x], cover, 3 * len); + if(x == m_last_x+1) + { + m_cur_span->len += 3 * (coord_type)len; + } + else + { + m_cur_span++; + m_cur_span->x = (coord_type)(x + m_min_x); + m_cur_span->len = 3 * (coord_type)len; + m_cur_span->covers = &m_covers[3 * x]; + } + m_last_x = x + len - 1; + } - //-------------------------------------------------------------------- - void reset_spans() - { - m_last_x = 0x7FFFFFF0; - m_cur_span = &m_spans[0]; - } + //-------------------------------------------------------------------- + void finalize(int y) + { + m_y = y; + } - //-------------------------------------------------------------------- - int y() const { return m_y; } - unsigned num_spans() const { return unsigned(m_cur_span - &m_spans[0]); } - const_iterator begin() const { return &m_spans[1]; } - iterator begin() { return &m_spans[1]; } + //-------------------------------------------------------------------- + void reset_spans() + { + m_last_x = 0x7FFFFFF0; + m_cur_span = &m_spans[0]; + } - private: - scanline_u8_subpix(const self_type&); - const self_type& operator = (const self_type&); + //-------------------------------------------------------------------- + int y() const { return m_y; } + unsigned num_spans() const { return unsigned(m_cur_span - &m_spans[0]); } + const_iterator begin() const { return &m_spans[1]; } + iterator begin() { return &m_spans[1]; } - private: - int m_min_x; - int m_last_x; - int m_y; - pod_array m_covers; - pod_array m_spans; - span* m_cur_span; - }; + private: + scanline_u8_subpix(const self_type&); + const self_type& operator = (const self_type&); + + private: + int m_min_x; + int m_last_x; + int m_y; + pod_array m_covers; + pod_array m_spans; + span* m_cur_span; + }; } diff --git a/src/servers/app/drawing/Painter/AGGTextRenderer.cpp b/src/servers/app/drawing/Painter/AGGTextRenderer.cpp index 85b1af7895..ce3224b13c 100644 --- a/src/servers/app/drawing/Painter/AGGTextRenderer.cpp +++ b/src/servers/app/drawing/Painter/AGGTextRenderer.cpp @@ -25,6 +25,7 @@ # include #endif +#include "GlobalSubpixelSettings.h" #include "GlyphLayoutEngine.h" #include "IntRect.h" @@ -32,7 +33,9 @@ // constructor AGGTextRenderer::AGGTextRenderer(renderer_subpix_type& subpixRenderer, renderer_type& solidRenderer, renderer_bin_type& binRenderer, - scanline_unpacked_type& scanline) + scanline_unpacked_type& scanline, + scanline_unpacked_subpix_type& subpixScanline, + rasterizer_subpix_type& subpixRasterizer) : fPathAdaptor() , fGray8Adaptor() , fGray8Scanline() @@ -47,6 +50,8 @@ AGGTextRenderer::AGGTextRenderer(renderer_subpix_type& subpixRenderer, , fBinRenderer(binRenderer) , fSubpixRenderer(subpixRenderer) , fScanline(scanline) + , fSubpixScanline(subpixScanline) + , fSubpixRasterizer(subpixRasterizer) , fRasterizer() , fHinted(true) @@ -100,6 +105,7 @@ AGGTextRenderer::SetAntialiasing(bool antialiasing) } } + typedef agg::conv_transform conv_font_trans_type; @@ -136,12 +142,18 @@ class AGGTextRenderer::StringRenderer { void Start() { fRenderer.fRasterizer.reset(); + fRenderer.fSubpixRasterizer.reset(); } void Finish(double x, double y) { if (fVector) { - agg::render_scanlines(fRenderer.fRasterizer, fRenderer.fScanline, - fRenderer.fSolidRenderer); + if (gSubpixelAntialiasing) { + agg::render_scanlines(fRenderer.fSubpixRasterizer, + fRenderer.fSubpixScanline, fRenderer.fSubpixRenderer); + } else { + agg::render_scanlines(fRenderer.fRasterizer, + fRenderer.fScanline, fRenderer.fSolidRenderer); + } } if (fNextCharPos) { @@ -231,10 +243,22 @@ class AGGTextRenderer::StringRenderer { case glyph_data_outline: { fVector = true; - if (fRenderer.fContour.width() == 0.0) { - fRenderer.fRasterizer.add_path(fTransformedGlyph); + if (gSubpixelAntialiasing) { + if (fRenderer.fContour.width() == 0.0) { + fRenderer.fSubpixRasterizer.add_path( + fTransformedGlyph); + } else { + fRenderer.fSubpixRasterizer.add_path( + fTransformedContour); + } } else { - fRenderer.fRasterizer.add_path(fTransformedContour); + if (fRenderer.fContour.width() == 0.0) { + fRenderer.fRasterizer.add_path( + fTransformedGlyph); + } else { + fRenderer.fRasterizer.add_path( + fTransformedContour); + } } #if SHOW_GLYPH_BOUNDS agg::path_storage p; @@ -245,7 +269,11 @@ class AGGTextRenderer::StringRenderer { p.close_polygon(); agg::conv_stroke ps(p); ps.width(1.0); - fRenderer.fRasterizer.add_path(ps); + if (gSubpixelAntialiasing) { + fRenderer.fSubpixRasterizer.add_path(ps); + } else { + fRenderer.fRasterizer.add_path(ps); + } #endif break; diff --git a/src/servers/app/drawing/Painter/AGGTextRenderer.h b/src/servers/app/drawing/Painter/AGGTextRenderer.h index cbb49b1354..04246c4389 100644 --- a/src/servers/app/drawing/Painter/AGGTextRenderer.h +++ b/src/servers/app/drawing/Painter/AGGTextRenderer.h @@ -25,7 +25,9 @@ class AGGTextRenderer { AGGTextRenderer(renderer_subpix_type& subpixRenderer, renderer_type& solidRenderer, renderer_bin_type& binRenderer, - scanline_unpacked_type& scanline); + scanline_unpacked_type& scanline, + scanline_unpacked_subpix_type& subpixScanline, + rasterizer_subpix_type& subpixRasterizer); virtual ~AGGTextRenderer(); void SetFont(const ServerFont &font); @@ -73,6 +75,8 @@ class AGGTextRenderer { renderer_bin_type& fBinRenderer; renderer_subpix_type& fSubpixRenderer; scanline_unpacked_type& fScanline; + scanline_unpacked_subpix_type& fSubpixScanline; + rasterizer_subpix_type& fSubpixRasterizer; rasterizer_type fRasterizer; // NOTE: the object has it's own rasterizer object // since it might be using a different gamma setting diff --git a/src/servers/app/drawing/Painter/GlobalSubpixelSettings.cpp b/src/servers/app/drawing/Painter/GlobalSubpixelSettings.cpp new file mode 100644 index 0000000000..7d7ed75d52 --- /dev/null +++ b/src/servers/app/drawing/Painter/GlobalSubpixelSettings.cpp @@ -0,0 +1,14 @@ +/* + * Copyright 2008, Andrej Spielmann . + * All rights reserved. Distributed under the terms of the MIT License. + */ + +//! Global settings of the app server regarding antialiasing and font hinting + +#include "GlobalSubpixelSettings.h" + +// NOTE: all these are initialized in DesktopSettings.cpp +bool gSubpixelAntialiasing; +bool gDefaultHinting; +unsigned char gSubpixelAverageWeight; +bool gSubpixelOrderingRGB; diff --git a/src/servers/app/drawing/Painter/GlobalSubpixelSettings.h b/src/servers/app/drawing/Painter/GlobalSubpixelSettings.h new file mode 100644 index 0000000000..7a76e8780e --- /dev/null +++ b/src/servers/app/drawing/Painter/GlobalSubpixelSettings.h @@ -0,0 +1,29 @@ +/* + * Copyright 2008, Andrej Spielmann . + * All rights reserved. Distributed under the terms of the MIT License. + * + * Global settings of the app server regarding antialiasing and font hinting + * + */ + +#ifndef GLOBAL_SUBPIXEL_SETTINGS_H +#define GLOBAL_SUBPIXEL_SETTINGS_H + +#define AVERAGE_BASED_SUBPIXEL_FILTERING + +extern bool gSubpixelAntialiasing; +extern bool gDefaultHinting; + +// The weight with which the average of the subpixels is applied to counter +// color fringes (0 = full sharpness ... 255 = grayscale anti-aliasing) +extern unsigned char gSubpixelAverageWeight; + +// There are two types of LCD displays in general - the more common have +// sub - pixels physically ordered as RGB within a pixel, but some are BGR. +// Sub - pixel antialiasing optimised for one ordering obviously doesn't work +// on the other. +extern bool gSubpixelOrderingRGB; + +#endif // GLOBAL_SUBPIXEL_SETTINGS_H + + diff --git a/src/servers/app/drawing/Painter/Jamfile b/src/servers/app/drawing/Painter/Jamfile index 330d90b10f..f957b5b6d6 100644 --- a/src/servers/app/drawing/Painter/Jamfile +++ b/src/servers/app/drawing/Painter/Jamfile @@ -13,6 +13,7 @@ UseFreeTypeHeaders ; SEARCH_SOURCE += [ FDirName $(SUBDIR) drawing_modes ] ; StaticLibrary libpainter.a : + GlobalSubpixelSettings.cpp Painter.cpp Transformable.cpp diff --git a/src/servers/app/drawing/Painter/Painter.cpp b/src/servers/app/drawing/Painter/Painter.cpp index 05e2334a0d..e7a4355a37 100644 --- a/src/servers/app/drawing/Painter/Painter.cpp +++ b/src/servers/app/drawing/Painter/Painter.cpp @@ -40,6 +40,7 @@ #include #include "DrawingMode.h" +#include "GlobalSubpixelSettings.h" #include "PatternHandler.h" #include "RenderingBuffer.h" #include "ServerBitmap.h" @@ -61,7 +62,6 @@ using std::nothrow; #define CHECK_CLIPPING if (!fValidClipping) return BRect(0, 0, -1, -1); #define CHECK_CLIPPING_NO_RETURN if (!fValidClipping) return; - // constructor Painter::Painter() : fBuffer(), @@ -69,6 +69,9 @@ Painter::Painter() fBaseRenderer(fPixelFormat), fUnpackedScanline(), fPackedScanline(), + fSubpixPackedScanline(), + fSubpixUnpackedScanline(), + fSubpixRasterizer(), fRasterizer(), fSubpixRenderer(fBaseRenderer), fRenderer(fBaseRenderer), @@ -90,15 +93,16 @@ Painter::Painter() fLineCapMode(B_BUTT_CAP), fLineJoinMode(B_MITER_JOIN), fMiterLimit(B_DEFAULT_MITER_LIMIT), - fSubpixelAntialias(true), fPatternHandler(), - fTextRenderer(fSubpixRenderer, fRenderer, fRendererBin, fUnpackedScanline) + fTextRenderer(fSubpixRenderer, fRenderer, fRendererBin, fUnpackedScanline, + fSubpixUnpackedScanline, fSubpixRasterizer) { fPixelFormat.SetDrawingMode(fDrawingMode, fAlphaSrcMode, fAlphaFncMode, false); #if ALIASED_DRAWING fRasterizer.gamma(agg::gamma_threshold(0.5)); + fSubpixRasterizer.gamma(agg:gamma_threshold(0.5)); #endif } @@ -211,6 +215,7 @@ Painter::ConstrainClipping(const BRegion* region) if (fValidClipping) { clipping_rect cb = fClippingRegion->FrameInt(); fRasterizer.clip_box(cb.left, cb.top, cb.right + 1, cb.bottom + 1); + fSubpixRasterizer.clip_box(cb.left, cb.top, cb.right + 1, cb.bottom + 1); } } @@ -244,13 +249,6 @@ Painter::SetDrawingMode(drawing_mode mode) } } -void -Painter::SetSubpixelAntialiasing(bool subpixelAntialias) -{ - if (fSubpixelAntialias != subpixelAntialias) { - fSubpixelAntialias = subpixelAntialias; - } -} // SetBlendingMode void @@ -826,30 +824,61 @@ Painter::StrokeRoundRect(const BRect& r, float xRadius, float yRadius) const outer.rect(lt.x, lt.y, rb.x, rb.y); outer.radius(xRadius, yRadius); - fRasterizer.reset(); - fRasterizer.add_path(outer); + if (gSubpixelAntialiasing) { + fSubpixRasterizer.reset(); + fSubpixRasterizer.add_path(outer); + + // don't add an inner hole if the "size is negative", this avoids some + // defects that can be observed on R5 and could be regarded as a bug. + if (2 * fPenSize < rb.x - lt.x && 2 * fPenSize < rb.y - lt.y) { + agg::rounded_rect inner; + inner.rect(lt.x + fPenSize, lt.y + fPenSize, rb.x - fPenSize, + rb.y - fPenSize); + inner.radius(max_c(0.0, xRadius - fPenSize), + max_c(0.0, yRadius - fPenSize)); - // don't add an inner hole if the "size is negative", this avoids some - // defects that can be observed on R5 and could be regarded as a bug. - if (2 * fPenSize < rb.x - lt.x && 2 * fPenSize < rb.y - lt.y) { - agg::rounded_rect inner; - inner.rect(lt.x + fPenSize, lt.y + fPenSize, rb.x - fPenSize, rb.y - fPenSize); - inner.radius(max_c(0.0, xRadius - fPenSize), max_c(0.0, yRadius - fPenSize)); + fSubpixRasterizer.add_path(inner); + } - fRasterizer.add_path(inner); + // make the inner rect work as a hole + fSubpixRasterizer.filling_rule(agg::fill_even_odd); + + if (fPenSize > 2) + agg::render_scanlines(fSubpixRasterizer, fSubpixPackedScanline, + fSubpixRenderer); + else + agg::render_scanlines(fSubpixRasterizer, fSubpixUnpackedScanline, + fSubpixRenderer); + + fSubpixRasterizer.filling_rule(agg::fill_non_zero); + } else { + fRasterizer.reset(); + fRasterizer.add_path(outer); + + // don't add an inner hole if the "size is negative", this avoids some + // defects that can be observed on R5 and could be regarded as a bug. + if (2 * fPenSize < rb.x - lt.x && 2 * fPenSize < rb.y - lt.y) { + agg::rounded_rect inner; + inner.rect(lt.x + fPenSize, lt.y + fPenSize, rb.x - fPenSize, + rb.y - fPenSize); + inner.radius(max_c(0.0, xRadius - fPenSize), + max_c(0.0, yRadius - fPenSize)); + + fRasterizer.add_path(inner); + } + + // make the inner rect work as a hole + fRasterizer.filling_rule(agg::fill_even_odd); + + if (fPenSize > 2) + agg::render_scanlines(fRasterizer, fPackedScanline, fRenderer); + else + agg::render_scanlines(fRasterizer, fUnpackedScanline, fRenderer); + + // reset to default + fRasterizer.filling_rule(agg::fill_non_zero); } - // make the inner rect work as a hole - fRasterizer.filling_rule(agg::fill_even_odd); - - if (fPenSize > 2) - agg::render_scanlines(fRasterizer, fPackedScanline, fRenderer); - else - agg::render_scanlines(fRasterizer, fUnpackedScanline, fRenderer); - - // reset to default - fRasterizer.filling_rule(agg::fill_non_zero); - return _Clipped(_BoundingBox(outer)); } } @@ -932,20 +961,39 @@ Painter::DrawEllipse(BRect r, bool fill) const yRadius + inset, divisions); - fRasterizer.reset(); - fRasterizer.add_path(outer); - fRasterizer.add_path(inner); + if (gSubpixelAntialiasing) { + fSubpixRasterizer.reset(); + fSubpixRasterizer.add_path(outer); + fSubpixRasterizer.add_path(inner); - // make the inner ellipse work as a hole - fRasterizer.filling_rule(agg::fill_even_odd); + // make the inner ellipse work as a hole + fSubpixRasterizer.filling_rule(agg::fill_even_odd); - if (fPenSize > 4) - agg::render_scanlines(fRasterizer, fPackedScanline, fRenderer); - else - agg::render_scanlines(fRasterizer, fUnpackedScanline, fRenderer); + if (fPenSize > 4) + agg::render_scanlines(fSubpixRasterizer, fSubpixPackedScanline, + fSubpixRenderer); + else + agg::render_scanlines(fSubpixRasterizer, fSubpixUnpackedScanline, + fSubpixRenderer); - // reset to default - fRasterizer.filling_rule(agg::fill_non_zero); + // reset to default + fSubpixRasterizer.filling_rule(agg::fill_non_zero); + } else { + fRasterizer.reset(); + fRasterizer.add_path(outer); + fRasterizer.add_path(inner); + + // make the inner ellipse work as a hole + fRasterizer.filling_rule(agg::fill_even_odd); + + if (fPenSize > 4) + agg::render_scanlines(fRasterizer, fPackedScanline, fRenderer); + else + agg::render_scanlines(fRasterizer, fUnpackedScanline, fRenderer); + + // reset to default + fRasterizer.filling_rule(agg::fill_non_zero); + } return _Clipped(_BoundingBox(outer)); } @@ -1131,6 +1179,7 @@ Painter::InvertRect(const BRect& r) const return _Clipped(r); } + // #pragma mark - private // _Transform @@ -1968,10 +2017,20 @@ Painter::_StrokePath(VertexSource& path) const stroke.line_join(agg_line_join_mode_for(fLineJoinMode)); stroke.miter_limit(fMiterLimit); - fRasterizer.reset(); - fRasterizer.add_path(stroke); + if (gSubpixelAntialiasing) { + + fSubpixRasterizer.reset(); + fSubpixRasterizer.add_path(stroke); + + agg::render_scanlines(fSubpixRasterizer, + fSubpixPackedScanline, fSubpixRenderer); + } else { - agg::render_scanlines(fRasterizer, fPackedScanline, fRenderer); + fRasterizer.reset(); + fRasterizer.add_path(stroke); + + agg::render_scanlines(fRasterizer, fPackedScanline, fRenderer); + } BRect touched = _BoundingBox(path); float penSize = ceilf(fPenSize / 2.0); @@ -1985,9 +2044,17 @@ template BRect Painter::_FillPath(VertexSource& path) const { - fRasterizer.reset(); - fRasterizer.add_path(path); - agg::render_scanlines(fRasterizer, fPackedScanline, fRenderer); + if (gSubpixelAntialiasing) { + + fSubpixRasterizer.reset(); + fSubpixRasterizer.add_path(path); + agg::render_scanlines(fSubpixRasterizer, + fSubpixPackedScanline, fSubpixRenderer); + } else { + fRasterizer.reset(); + fRasterizer.add_path(path); + agg::render_scanlines(fRasterizer, fPackedScanline, fRenderer); + } return _Clipped(_BoundingBox(path)); } diff --git a/src/servers/app/drawing/Painter/Painter.h b/src/servers/app/drawing/Painter/Painter.h index 00a39dbc9e..427b430b0a 100644 --- a/src/servers/app/drawing/Painter/Painter.h +++ b/src/servers/app/drawing/Painter/Painter.h @@ -7,6 +7,7 @@ * rendering pipe-lines for stroke, fills, bitmap and text rendering. * */ + #ifndef PAINTER_H #define PAINTER_H @@ -23,7 +24,6 @@ #include #include - class BBitmap; class BRegion; class DrawState; @@ -73,9 +73,6 @@ class Painter { void SetDrawingMode(drawing_mode mode); inline drawing_mode DrawingMode() const { return fDrawingMode; } - void SetSubpixelAntialiasing(bool subpixelAntialias); - bool SubpixelAntialiasing() const - { return fSubpixelAntialias; } void SetBlendingMode(source_alpha srcAlpha, alpha_function alphaFunc); @@ -272,6 +269,9 @@ mutable renderer_base fBaseRenderer; mutable scanline_unpacked_type fUnpackedScanline; mutable scanline_packed_type fPackedScanline; +mutable scanline_packed_subpix_type fSubpixPackedScanline; +mutable scanline_unpacked_subpix_type fSubpixUnpackedScanline; +mutable rasterizer_subpix_type fSubpixRasterizer; mutable rasterizer_type fRasterizer; mutable renderer_subpix_type fSubpixRenderer; mutable renderer_type fRenderer; @@ -294,7 +294,6 @@ mutable agg::conv_curve fCurve; cap_mode fLineCapMode; join_mode fLineJoinMode; float fMiterLimit; - bool fSubpixelAntialias; PatternHandler fPatternHandler; diff --git a/src/servers/app/drawing/Painter/agg_rasterizer_scanline_aa_subpix.h b/src/servers/app/drawing/Painter/agg_rasterizer_scanline_aa_subpix.h new file mode 100644 index 0000000000..806f8c964e --- /dev/null +++ b/src/servers/app/drawing/Painter/agg_rasterizer_scanline_aa_subpix.h @@ -0,0 +1,547 @@ +/* + * Copyright 2008, Andrej Spielmann . + * All rights reserved. Distributed under the terms of the MIT License. + * + * Copyright 2002-2004 Maxim Shemanarev (http://www.antigrain.com) + * + * + */ + +#ifndef AGG_RASTERIZER_SCANLINE_AA_SUBPIX_INCLUDED +#define AGG_RASTERIZER_SCANLINE_AA_SUBPIX_INCLUDED + +#include "agg_rasterizer_cells_aa.h" +#include "agg_rasterizer_sl_clip.h" +#include "agg_gamma_functions.h" + + +namespace agg +{ + template class rasterizer_scanline_aa_subpix + { + enum status + { + status_initial, + status_move_to, + status_line_to, + status_closed + }; + + public: + typedef Clip clip_type; + typedef typename Clip::conv_type conv_type; + typedef typename Clip::coord_type coord_type; + + enum aa_scale_e + { + aa_shift = 8, + aa_scale = 1 << aa_shift, + aa_mask = aa_scale - 1, + aa_scale2 = aa_scale * 2, + aa_mask2 = aa_scale2 - 1 + }; + + //-------------------------------------------------------------------- + rasterizer_scanline_aa_subpix() : + m_outline(), + m_clipper(), + m_filling_rule(fill_non_zero), + m_auto_close(true), + m_start_x(0), + m_start_y(0), + m_status(status_initial) + { + int i; + for(i = 0; i < aa_scale; i++) m_gamma[i] = i; + } + + //-------------------------------------------------------------------- + template + rasterizer_scanline_aa_subpix(const GammaF& gamma_function) : + m_outline(), + m_clipper(m_outline), + m_filling_rule(fill_non_zero), + m_auto_close(true), + m_start_x(0), + m_start_y(0), + m_status(status_initial) + { + gamma(gamma_function); + } + + //-------------------------------------------------------------------- + void reset(); + void reset_clipping(); + void clip_box(double x1, double y1, double x2, double y2); + void filling_rule(filling_rule_e filling_rule); + void auto_close(bool flag) { m_auto_close = flag; } + + //-------------------------------------------------------------------- + template void gamma(const GammaF& gamma_function) + { + int i; + for(i = 0; i < aa_scale; i++) + { + m_gamma[i] = uround(gamma_function(double(i) / aa_mask) * aa_mask); + } + } + + //-------------------------------------------------------------------- + unsigned apply_gamma(unsigned cover) const + { + return m_gamma[cover]; + } + + //-------------------------------------------------------------------- + void move_to(int x, int y); + void line_to(int x, int y); + void move_to_d(double x, double y); + void line_to_d(double x, double y); + void close_polygon(); + void add_vertex(double x, double y, unsigned cmd); + + void edge(int x1, int y1, int x2, int y2); + void edge_d(double x1, double y1, double x2, double y2); + + //------------------------------------------------------------------- + template + void add_path(VertexSource& vs, unsigned path_id=0) + { + double x; + double y; + + unsigned cmd; + vs.rewind(path_id); + if(m_outline.sorted()) reset(); + while(!is_stop(cmd = vs.vertex(&x, &y))) + { + if (is_vertex(cmd)) { + x *= 3; + } + add_vertex(x, y, cmd); + } + } + + //-------------------------------------------------------------------- + int min_x() const { return m_outline.min_x() / 3; } + int min_y() const { return m_outline.min_y(); } + int max_x() const { return m_outline.max_x() / 3; } + int max_y() const { return m_outline.max_y(); } + + //-------------------------------------------------------------------- + void sort(); + bool rewind_scanlines(); + bool navigate_scanline(int y); + + //-------------------------------------------------------------------- + AGG_INLINE unsigned calculate_alpha(int area) const + { + int cover = area >> (poly_subpixel_shift*2 + 1 - aa_shift); + + if(cover < 0) cover = -cover; + if(m_filling_rule == fill_even_odd) + { + cover &= aa_mask2; + if(cover > aa_scale) + { + cover = aa_scale2 - cover; + } + } + if(cover > aa_mask) cover = aa_mask; + return m_gamma[cover]; + } + + //-------------------------------------------------------------------- + template bool sweep_scanline(Scanline& sl) + { + for(;;) + { + if(m_scan_y > m_outline.max_y()) return false; + sl.reset_spans(); + unsigned num_cells = m_outline.scanline_num_cells(m_scan_y); + const cell_aa* const* cells = m_outline.scanline_cells(m_scan_y); + int cover = 0; + int cover2 = 0; + int cover3 = 0; + + while(num_cells) + { + const cell_aa* cur_cell = *cells; + int x = cur_cell->x; + int area1 = cur_cell->area; + int area2; + int area3; + unsigned alpha1; + unsigned alpha2; + unsigned alpha3; + + int last_cover = cover3; + cover = cover3; + cover += cur_cell->cover; + + while(--num_cells) + { + cur_cell = *++cells; + if(cur_cell->x != x) break; + area1 += cur_cell->area; + cover += cur_cell->cover; + } + + if (x % 3 == 0) + { + if (cur_cell->x == x + 1) + { + area2 = cur_cell->area; + cover2 = cover + cur_cell->cover; + + while (--num_cells) + { + cur_cell = *++cells; + if (cur_cell->x != x+1) break; + area2 += cur_cell->area; + cover2 += cur_cell->cover; + } + } + else + { + area2 = 0; + cover2 = cover; + } + + if (cur_cell->x == x + 2) + { + area3 = cur_cell->area; + cover3 = cover2 + cur_cell->cover; + + while (--num_cells) + { + cur_cell = *++cells; + if (cur_cell->x != x+2) break; + area3 += cur_cell->area; + cover3 += cur_cell->cover; + } + } + else + { + area3 = 0; + cover3 = cover2; + } + } + else if (x % 3 == 1) + { + area2 = area1; + area1 = 0; + cover2 = cover; + cover = last_cover; + if (cur_cell->x == x+1) + { + area3 = cur_cell->area; + cover3 = cover2 + cur_cell->cover; + + while (--num_cells) + { + cur_cell = *++cells; + if (cur_cell->x != x+1) break; + area3 += cur_cell->area; + cover3 += cur_cell->cover; + } + } + else + { + area3 = 0; + cover3 = cover2; + } + } + else // if (x % 3 == 2) + { + area3 = area1; + area2 = 0; + area1 = 0; + cover3 = cover; + cover = last_cover; + cover2 = last_cover; + } + + alpha1 = area1 ? calculate_alpha((cover + << (poly_subpixel_shift + 1)) - area1) : 0; + alpha2 = area2 ? calculate_alpha((cover2 + << (poly_subpixel_shift + 1)) - area2) : 0; + alpha3 = area3 ? calculate_alpha((cover3 + << (poly_subpixel_shift + 1)) - area3) : 0; + if(alpha1 || alpha2 || alpha3) + { + x += 3 - (x % 3); + if (area1 && !area2 && area3) + { + alpha2 = calculate_alpha(cover + << (poly_subpixel_shift + 1)); + } + else if (num_cells && cur_cell->x >= x) + { + if (area1 && !area2) + { + alpha2 = calculate_alpha(cover + << (poly_subpixel_shift + 1)); + alpha3 = alpha2; + } + if (area2 && !area3) + { + alpha3 = calculate_alpha(cover2 + << (poly_subpixel_shift + 1)); + } + } + if (!area1) + { + if (area2) + { + alpha1 = calculate_alpha(cover + << (poly_subpixel_shift + 1)); + } + else if (area3) + { + alpha2 = calculate_alpha(cover + << (poly_subpixel_shift + 1)); + alpha1 = alpha2; + } + } + sl.add_cell(x / 3 - 1, alpha1, alpha2, alpha3); + } + + if (num_cells && cur_cell->x - x >= 3) + { + alpha1 = calculate_alpha(cover3 + << (poly_subpixel_shift + 1)); + sl.add_span(x / 3, cur_cell->x / 3 - x / 3, alpha1); + } + } + + if(sl.num_spans()) break; + ++m_scan_y; + } + + sl.finalize(m_scan_y); + ++m_scan_y; + return true; + } + + //-------------------------------------------------------------------- + bool hit_test(int tx, int ty); + + + private: + //-------------------------------------------------------------------- + // Disable copying + rasterizer_scanline_aa_subpix(const rasterizer_scanline_aa_subpix&); + const rasterizer_scanline_aa_subpix& + operator = (const rasterizer_scanline_aa_subpix&); + + private: + rasterizer_cells_aa m_outline; + clip_type m_clipper; + int m_gamma[aa_scale]; + filling_rule_e m_filling_rule; + bool m_auto_close; + coord_type m_start_x; + coord_type m_start_y; + unsigned m_status; + int m_scan_y; + }; + + + + + + + + + + + + + //------------------------------------------------------------------------ + template + void rasterizer_scanline_aa_subpix::reset() + { + m_outline.reset(); + m_status = status_initial; + } + + //------------------------------------------------------------------------ + template + void rasterizer_scanline_aa_subpix::filling_rule(filling_rule_e filling_rule) + { + m_filling_rule = filling_rule; + } + + //------------------------------------------------------------------------ + template + void rasterizer_scanline_aa_subpix::clip_box(double x1, double y1, + double x2, double y2) + { + reset(); + m_clipper.clip_box(3 * conv_type::downscale(x1), conv_type::upscale(y1), + conv_type::upscale(3 * x2), conv_type::upscale(y2)); + } + + //------------------------------------------------------------------------ + template + void rasterizer_scanline_aa_subpix::reset_clipping() + { + reset(); + m_clipper.reset_clipping(); + } + + //------------------------------------------------------------------------ + template + void rasterizer_scanline_aa_subpix::close_polygon() + { + if(m_status == status_line_to) + { + m_clipper.line_to(m_outline, m_start_x, m_start_y); + m_status = status_closed; + } + } + + //------------------------------------------------------------------------ + template + void rasterizer_scanline_aa_subpix::move_to(int x, int y) + { + if(m_outline.sorted()) reset(); + if(m_auto_close) close_polygon(); + m_clipper.move_to(m_start_x = conv_type::downscale(x), + m_start_y = conv_type::downscale(y)); + m_status = status_move_to; + } + + //------------------------------------------------------------------------ + template + void rasterizer_scanline_aa_subpix::line_to(int x, int y) + { + m_clipper.line_to(m_outline, + conv_type::downscale(x), + conv_type::downscale(y)); + m_status = status_line_to; + } + + //------------------------------------------------------------------------ + template + void rasterizer_scanline_aa_subpix::move_to_d(double x, double y) + { + if(m_outline.sorted()) reset(); + if(m_auto_close) close_polygon(); + m_clipper.move_to(m_start_x = conv_type::upscale(x), + m_start_y = conv_type::upscale(y)); + m_status = status_move_to; + } + + //------------------------------------------------------------------------ + template + void rasterizer_scanline_aa_subpix::line_to_d(double x, double y) + { + m_clipper.line_to(m_outline, + conv_type::upscale(x), + conv_type::upscale(y)); + m_status = status_line_to; + } + + //------------------------------------------------------------------------ + template + void rasterizer_scanline_aa_subpix::add_vertex(double x, double y, unsigned cmd) + { + if(is_move_to(cmd)) + { + move_to_d(x, y); + } + else + if(is_vertex(cmd)) + { + line_to_d(x, y); + } + else + if(is_close(cmd)) + { + close_polygon(); + } + } + + //------------------------------------------------------------------------ + template + void rasterizer_scanline_aa_subpix::edge(int x1, int y1, int x2, int y2) + { + if(m_outline.sorted()) reset(); + m_clipper.move_to(conv_type::downscale(x1), conv_type::downscale(y1)); + m_clipper.line_to(m_outline, + conv_type::downscale(x2), + conv_type::downscale(y2)); + m_status = status_move_to; + } + + //------------------------------------------------------------------------ + template + void rasterizer_scanline_aa_subpix::edge_d(double x1, double y1, + double x2, double y2) + { + if(m_outline.sorted()) reset(); + m_clipper.move_to(conv_type::upscale(x1), conv_type::upscale(y1)); + m_clipper.line_to(m_outline, + conv_type::upscale(x2), + conv_type::upscale(y2)); + m_status = status_move_to; + } + + //------------------------------------------------------------------------ + template + void rasterizer_scanline_aa_subpix::sort() + { + m_outline.sort_cells(); + } + + //------------------------------------------------------------------------ + template + AGG_INLINE bool rasterizer_scanline_aa_subpix::rewind_scanlines() + { + if(m_auto_close) close_polygon(); + m_outline.sort_cells(); + if(m_outline.total_cells() == 0) + { + return false; + } + m_scan_y = m_outline.min_y(); + return true; + } + + + //------------------------------------------------------------------------ + template + AGG_INLINE bool rasterizer_scanline_aa_subpix::navigate_scanline(int y) + { + if(m_auto_close) close_polygon(); + m_outline.sort_cells(); + if(m_outline.total_cells() == 0 || + y < m_outline.min_y() || + y > m_outline.max_y()) + { + return false; + } + m_scan_y = y; + return true; + } + + //------------------------------------------------------------------------ + template + bool rasterizer_scanline_aa_subpix::hit_test(int tx, int ty) + { + if(!navigate_scanline(ty)) return false; + scanline_hit_test sl(tx); + sweep_scanline(sl); + return sl.hit(); + } + + + +} + + + +#endif + diff --git a/src/servers/app/drawing/Painter/agg_renderer_region.h b/src/servers/app/drawing/Painter/agg_renderer_region.h index 7f85bb27de..e761129744 100644 --- a/src/servers/app/drawing/Painter/agg_renderer_region.h +++ b/src/servers/app/drawing/Painter/agg_renderer_region.h @@ -23,339 +23,327 @@ namespace agg { - //----------------------------------------------------------renderer_region - template class renderer_region - { - public: - typedef PixelFormat pixfmt_type; - typedef typename pixfmt_type::color_type color_type; - typedef renderer_base base_ren_type; - - //-------------------------------------------------------------------- - renderer_region(pixfmt_type& ren) : - m_ren(ren), - m_region(NULL), - m_curr_cb(0), - m_bounds(m_ren.xmin(), m_ren.ymin(), m_ren.xmax(), m_ren.ymax()) - { - } - - //-------------------------------------------------------------------- - const pixfmt_type& ren() const { return m_ren.ren(); } - pixfmt_type& ren() { return m_ren.ren(); } - - //-------------------------------------------------------------------- - unsigned width() const { return m_ren.width(); } - unsigned height() const { return m_ren.height(); } - - //-------------------------------------------------------------------- - const rect_i& clip_box() const { return m_ren.clip_box(); } - int xmin() const { return m_ren.xmin(); } - int ymin() const { return m_ren.ymin(); } - int xmax() const { return m_ren.xmax(); } - int ymax() const { return m_ren.ymax(); } - - //-------------------------------------------------------------------- - const rect_i& bounding_clip_box() const { return m_bounds; } - int bounding_xmin() const { return m_bounds.x1; } - int bounding_ymin() const { return m_bounds.y1; } - int bounding_xmax() const { return m_bounds.x2; } - int bounding_ymax() const { return m_bounds.y2; } - - //-------------------------------------------------------------------- - void first_clip_box() - { - m_curr_cb = 0; - if(m_region && m_region->CountRects() > 0) - { - clipping_rect cb = m_region->RectAtInt(0); - m_ren.clip_box_naked(cb.left, cb.top, cb.right, cb.bottom); - } - else - m_ren.clip_box_naked(0, 0, -1, -1); - } - - //-------------------------------------------------------------------- - bool next_clip_box() - { - if(m_region && (int)(++m_curr_cb) < m_region->CountRects()) - { - clipping_rect cb = m_region->RectAtInt(m_curr_cb); - m_ren.clip_box_naked(cb.left, cb.top, cb.right, cb.bottom); - return true; - } - return false; - } - - //-------------------------------------------------------------------- - void reset_clipping(bool visibility) - { - m_ren.reset_clipping(visibility); - m_region = NULL; - m_curr_cb = 0; - m_bounds = m_ren.clip_box(); - } - - //-------------------------------------------------------------------- - void set_clipping_region(BRegion* region) - { - m_region = region; - if (m_region) { - clipping_rect r = m_region->FrameInt(); - if (r.left <= r.right && r.top <= r.bottom) { - // clip rect_i to frame buffer bounds - r.left = max_c(0, r.left); - r.top = max_c(0, r.top); - r.right = min_c((int)width() - 1, r.right); - r.bottom = min_c((int)height() - 1, r.bottom); - - if(r.left < m_bounds.x1) m_bounds.x1 = r.left; - if(r.top < m_bounds.y1) m_bounds.y1 = r.top; - if(r.right > m_bounds.x2) m_bounds.x2 = r.right; - if(r.bottom > m_bounds.y2) m_bounds.y2 = r.bottom; - } - } - } - - //-------------------------------------------------------------------- - void clear(const color_type& c) - { - m_ren.clear(c); - } - - //-------------------------------------------------------------------- - void copy_pixel(int x, int y, const color_type& c) - { - first_clip_box(); - do - { - if(m_ren.inbox(x, y)) - { - m_ren.ren().copy_pixel(x, y, c); - break; - } - } - while(next_clip_box()); - } - - //-------------------------------------------------------------------- - void blend_pixel(int x, int y, const color_type& c, cover_type cover) - { - first_clip_box(); - do - { - if(m_ren.inbox(x, y)) - { - m_ren.ren().blend_pixel(x, y, c, cover); - break; - } - } - while(next_clip_box()); - } - - //-------------------------------------------------------------------- - color_type pixel(int x, int y) const - { - first_clip_box(); - do - { - if(m_ren.inbox(x, y)) - { - return m_ren.ren().pixel(x, y); - } - } - while(next_clip_box()); - return color_type::no_color(); - } - - //-------------------------------------------------------------------- - void copy_hline(int x1, int y, int x2, const color_type& c) - { - first_clip_box(); - do - { - m_ren.copy_hline(x1, y, x2, c); - } - while(next_clip_box()); - } - - //-------------------------------------------------------------------- - void copy_vline(int x, int y1, int y2, const color_type& c) - { - first_clip_box(); - do - { - m_ren.copy_vline(x, y1, y2, c); - } - while(next_clip_box()); - } - - //-------------------------------------------------------------------- - void blend_hline(int x1, int y, int x2, - const color_type& c, cover_type cover) - { - first_clip_box(); - do - { - m_ren.blend_hline(x1, y, x2, c, cover); - } - while(next_clip_box()); - } + //----------------------------------------------------------renderer_region + template class renderer_region + { + public: + typedef PixelFormat pixfmt_type; + typedef typename pixfmt_type::color_type color_type; + typedef renderer_base base_ren_type; //-------------------------------------------------------------------- - void blend_hline_subpix(int x1, int y, int x2, - const color_type& c, cover_type cover) - { - first_clip_box(); - do - { - m_ren.blend_hline_subpix(x1, y, x2, c, cover); - } - while(next_clip_box()); - } - - //-------------------------------------------------------------------- - void blend_vline(int x, int y1, int y2, - const color_type& c, cover_type cover) - { - first_clip_box(); - do - { - m_ren.blend_vline(x, y1, y2, c, cover); - } - while(next_clip_box()); - } - - //-------------------------------------------------------------------- - void copy_bar(int x1, int y1, int x2, int y2, const color_type& c) - { - first_clip_box(); - do - { - m_ren.copy_bar(x1, y1, x2, y2, c); - } - while(next_clip_box()); - } - - //-------------------------------------------------------------------- - void blend_bar(int x1, int y1, int x2, int y2, - const color_type& c, cover_type cover) - { - first_clip_box(); - do - { - m_ren.blend_bar(x1, y1, x2, y2, c, cover); - } - while(next_clip_box()); - } - - - //-------------------------------------------------------------------- - void blend_solid_hspan(int x, int y, int len, - const color_type& c, const cover_type* covers) - { - first_clip_box(); - do - { - m_ren.blend_solid_hspan(x, y, len, c, covers); - } - while(next_clip_box()); - } + renderer_region(pixfmt_type& ren) : + m_ren(ren), + m_region(NULL), + m_curr_cb(0), + m_bounds(m_ren.xmin(), m_ren.ymin(), m_ren.xmax(), m_ren.ymax()) + { + } //-------------------------------------------------------------------- - void blend_solid_hspan_subpix(int x, int y, int len, - const color_type& c, const cover_type* covers) - { - first_clip_box(); - do - { - m_ren.blend_solid_hspan_subpix(x, y, len, c, covers); - } - while(next_clip_box()); - } + const pixfmt_type& ren() const { return m_ren.ren(); } + pixfmt_type& ren() { return m_ren.ren(); } - //-------------------------------------------------------------------- - void blend_solid_vspan(int x, int y, int len, - const color_type& c, const cover_type* covers) - { - first_clip_box(); - do - { - m_ren.blend_solid_vspan(x, y, len, c, covers); - } - while(next_clip_box()); - } + //-------------------------------------------------------------------- + unsigned width() const { return m_ren.width(); } + unsigned height() const { return m_ren.height(); } - //-------------------------------------------------------------------- - void blend_color_hspan(int x, int y, int len, - const color_type* colors, - const cover_type* covers, - cover_type cover = cover_full) - { - first_clip_box(); - do - { - m_ren.blend_color_hspan(x, y, len, colors, covers, cover); - } - while(next_clip_box()); - } + //-------------------------------------------------------------------- + const rect_i& clip_box() const { return m_ren.clip_box(); } + int xmin() const { return m_ren.xmin(); } + int ymin() const { return m_ren.ymin(); } + int xmax() const { return m_ren.xmax(); } + int ymax() const { return m_ren.ymax(); } - //-------------------------------------------------------------------- - void blend_color_vspan(int x, int y, int len, - const color_type* colors, - const cover_type* covers, - cover_type cover = cover_full) - { - first_clip_box(); - do - { - m_ren.blend_color_hspan(x, y, len, colors, covers, cover); - } - while(next_clip_box()); - } + //-------------------------------------------------------------------- + const rect_i& bounding_clip_box() const { return m_bounds; } + int bounding_xmin() const { return m_bounds.x1; } + int bounding_ymin() const { return m_bounds.y1; } + int bounding_xmax() const { return m_bounds.x2; } + int bounding_ymax() const { return m_bounds.y2; } - //-------------------------------------------------------------------- - void blend_color_hspan_no_clip(int x, int y, int len, - const color_type* colors, - const cover_type* covers, - cover_type cover = cover_full) - { - m_ren.blend_color_hspan_no_clip(x, y, len, colors, covers, cover); - } + //-------------------------------------------------------------------- + void first_clip_box() + { + m_curr_cb = 0; + if(m_region && m_region->CountRects() > 0) + { + clipping_rect cb = m_region->RectAtInt(0); + m_ren.clip_box_naked(cb.left, cb.top, cb.right, cb.bottom); + } + else + m_ren.clip_box_naked(0, 0, -1, -1); + } - //-------------------------------------------------------------------- - void blend_color_vspan_no_clip(int x, int y, int len, - const color_type* colors, - const cover_type* covers, - cover_type cover = cover_full) - { - m_ren.blend_color_vspan_no_clip(x, y, len, colors, covers, cover); - } + //-------------------------------------------------------------------- + bool next_clip_box() + { + if(m_region && (int)(++m_curr_cb) < m_region->CountRects()) + { + clipping_rect cb = m_region->RectAtInt(m_curr_cb); + m_ren.clip_box_naked(cb.left, cb.top, cb.right, cb.bottom); + return true; + } + return false; + } - //-------------------------------------------------------------------- - void copy_from(const rendering_buffer& from, - const rect_i* rc=0, - int x_to=0, - int y_to=0) - { - first_clip_box(); - do - { - m_ren.copy_from(from, rc, x_to, y_to); - } - while(next_clip_box()); - } + //-------------------------------------------------------------------- + void reset_clipping(bool visibility) + { + m_ren.reset_clipping(visibility); + m_region = NULL; + m_curr_cb = 0; + m_bounds = m_ren.clip_box(); + } - private: - renderer_region(const renderer_region&); - const renderer_region& - operator = (const renderer_region&); + //-------------------------------------------------------------------- + void set_clipping_region(BRegion* region) + { + m_region = region; + if (m_region) { + clipping_rect r = m_region->FrameInt(); + if (r.left <= r.right && r.top <= r.bottom) { + // clip rect_i to frame buffer bounds + r.left = max_c(0, r.left); + r.top = max_c(0, r.top); + r.right = min_c((int)width() - 1, r.right); + r.bottom = min_c((int)height() - 1, r.bottom); - base_ren_type m_ren; + if(r.left < m_bounds.x1) m_bounds.x1 = r.left; + if(r.top < m_bounds.y1) m_bounds.y1 = r.top; + if(r.right > m_bounds.x2) m_bounds.x2 = r.right; + if(r.bottom > m_bounds.y2) m_bounds.y2 = r.bottom; + } + } + } + + //-------------------------------------------------------------------- + void clear(const color_type& c) + { + m_ren.clear(c); + } + + //-------------------------------------------------------------------- + void copy_pixel(int x, int y, const color_type& c) + { + first_clip_box(); + do + { + if(m_ren.inbox(x, y)) + { + m_ren.ren().copy_pixel(x, y, c); + break; + } + } + while(next_clip_box()); + } + + //-------------------------------------------------------------------- + void blend_pixel(int x, int y, const color_type& c, cover_type cover) + { + first_clip_box(); + do + { + if(m_ren.inbox(x, y)) + { + m_ren.ren().blend_pixel(x, y, c, cover); + break; + } + } + while(next_clip_box()); + } + + //-------------------------------------------------------------------- + color_type pixel(int x, int y) const + { + first_clip_box(); + do + { + if(m_ren.inbox(x, y)) + { + return m_ren.ren().pixel(x, y); + } + } + while(next_clip_box()); + return color_type::no_color(); + } + + //-------------------------------------------------------------------- + void copy_hline(int x1, int y, int x2, const color_type& c) + { + first_clip_box(); + do + { + m_ren.copy_hline(x1, y, x2, c); + } + while(next_clip_box()); + } + + //-------------------------------------------------------------------- + void copy_vline(int x, int y1, int y2, const color_type& c) + { + first_clip_box(); + do + { + m_ren.copy_vline(x, y1, y2, c); + } + while(next_clip_box()); + } + + //-------------------------------------------------------------------- + void blend_hline(int x1, int y, int x2, + const color_type& c, cover_type cover) + { + first_clip_box(); + do + { + m_ren.blend_hline(x1, y, x2, c, cover); + } + while(next_clip_box()); + } + + //-------------------------------------------------------------------- + void blend_vline(int x, int y1, int y2, + const color_type& c, cover_type cover) + { + first_clip_box(); + do + { + m_ren.blend_vline(x, y1, y2, c, cover); + } + while(next_clip_box()); + } + + //-------------------------------------------------------------------- + void copy_bar(int x1, int y1, int x2, int y2, const color_type& c) + { + first_clip_box(); + do + { + m_ren.copy_bar(x1, y1, x2, y2, c); + } + while(next_clip_box()); + } + + //-------------------------------------------------------------------- + void blend_bar(int x1, int y1, int x2, int y2, + const color_type& c, cover_type cover) + { + first_clip_box(); + do + { + m_ren.blend_bar(x1, y1, x2, y2, c, cover); + } + while(next_clip_box()); + } + + + //-------------------------------------------------------------------- + void blend_solid_hspan(int x, int y, int len, + const color_type& c, const cover_type* covers) + { + first_clip_box(); + do + { + m_ren.blend_solid_hspan(x, y, len, c, covers); + } + while(next_clip_box()); + } + + //-------------------------------------------------------------------- + void blend_solid_hspan_subpix(int x, int y, int len, + const color_type& c, const cover_type* covers) + { + first_clip_box(); + do + { + m_ren.blend_solid_hspan_subpix(x, y, len, c, covers); + } + while(next_clip_box()); + } + + //-------------------------------------------------------------------- + void blend_solid_vspan(int x, int y, int len, + const color_type& c, const cover_type* covers) + { + first_clip_box(); + do + { + m_ren.blend_solid_vspan(x, y, len, c, covers); + } + while(next_clip_box()); + } + + //-------------------------------------------------------------------- + void blend_color_hspan(int x, int y, int len, + const color_type* colors, + const cover_type* covers, + cover_type cover = cover_full) + { + first_clip_box(); + do + { + m_ren.blend_color_hspan(x, y, len, colors, covers, cover); + } + while(next_clip_box()); + } + + //-------------------------------------------------------------------- + void blend_color_vspan(int x, int y, int len, + const color_type* colors, + const cover_type* covers, + cover_type cover = cover_full) + { + first_clip_box(); + do + { + m_ren.blend_color_hspan(x, y, len, colors, covers, cover); + } + while(next_clip_box()); + } + + //-------------------------------------------------------------------- + void blend_color_hspan_no_clip(int x, int y, int len, + const color_type* colors, + const cover_type* covers, + cover_type cover = cover_full) + { + m_ren.blend_color_hspan_no_clip(x, y, len, colors, covers, cover); + } + + //-------------------------------------------------------------------- + void blend_color_vspan_no_clip(int x, int y, int len, + const color_type* colors, + const cover_type* covers, + cover_type cover = cover_full) + { + m_ren.blend_color_vspan_no_clip(x, y, len, colors, covers, cover); + } + + //-------------------------------------------------------------------- + void copy_from(const rendering_buffer& from, + const rect_i* rc=0, + int x_to=0, + int y_to=0) + { + first_clip_box(); + do + { + m_ren.copy_from(from, rc, x_to, y_to); + } + while(next_clip_box()); + } + + private: + renderer_region(const renderer_region&); + const renderer_region& + operator = (const renderer_region&); + + base_ren_type m_ren; BRegion* m_region; - unsigned m_curr_cb; - rect_i m_bounds; - }; + unsigned m_curr_cb; + rect_i m_bounds; + }; } diff --git a/src/servers/app/drawing/Painter/agg_renderer_scanline_subpix.h b/src/servers/app/drawing/Painter/agg_renderer_scanline_subpix.h index 2f0e21b6f3..c6c29ba515 100644 --- a/src/servers/app/drawing/Painter/agg_renderer_scanline_subpix.h +++ b/src/servers/app/drawing/Painter/agg_renderer_scanline_subpix.h @@ -18,68 +18,66 @@ namespace agg { - //============================================render_scanline_subpix_solid - template - void render_scanline_subpix_solid(const Scanline& sl, - BaseRenderer& ren, - const ColorT& color) - { - int y = sl.y(); - unsigned num_spans = sl.num_spans(); - typename Scanline::const_iterator span = sl.begin(); + //============================================render_scanline_subpix_solid + template + void render_scanline_subpix_solid(const Scanline& sl, + BaseRenderer& ren, + const ColorT& color) + { + int y = sl.y(); + unsigned num_spans = sl.num_spans(); + typename Scanline::const_iterator span = sl.begin(); - for(;;) - { - int x = span->x; - if(span->len > 0) - { - ren.blend_solid_hspan_subpix(x, y, (unsigned)span->len, - color, - span->covers); - } - else - { - ren.blend_hline_subpix(x, y, (unsigned)(x - span->len - 1), - color, - *(span->covers)); - } - if(--num_spans == 0) break; - ++span; - } - } + for(;;) + { + int x = span->x; + if(span->len > 0) + { + ren.blend_solid_hspan_subpix(x, y, (unsigned)span->len, + color, + span->covers); + } + else + { + ren.blend_hline(x, y, (unsigned)(x - (span->len / 3) - 1), + color, + *(span->covers)); + } + if(--num_spans == 0) break; + ++span; + } + } + //==========================================renderer_scanline_subpix_solid + template class renderer_scanline_subpix_solid + { + public: + typedef BaseRenderer base_ren_type; + typedef typename base_ren_type::color_type color_type; - //==========================================renderer_scanline_subpix_solid - template class renderer_scanline_subpix_solid - { - public: - typedef BaseRenderer base_ren_type; - typedef typename base_ren_type::color_type color_type; + //-------------------------------------------------------------------- + renderer_scanline_subpix_solid() : m_ren(0) {} + renderer_scanline_subpix_solid(base_ren_type& ren) : m_ren(&ren) {} + void attach(base_ren_type& ren) + { + m_ren = &ren; + } - //-------------------------------------------------------------------- - renderer_scanline_subpix_solid() : m_ren(0) {} - renderer_scanline_subpix_solid(base_ren_type& ren) : m_ren(&ren) {} - void attach(base_ren_type& ren) - { - m_ren = &ren; - } + //-------------------------------------------------------------------- + void color(const color_type& c) { m_color = c; } + const color_type& color() const { return m_color; } - //-------------------------------------------------------------------- - void color(const color_type& c) { m_color = c; } - const color_type& color() const { return m_color; } + //-------------------------------------------------------------------- + void prepare() {} - //-------------------------------------------------------------------- - void prepare() {} - - //-------------------------------------------------------------------- - template void render(const Scanline& sl) - { - render_scanline_subpix_solid(sl, *m_ren, m_color); - } - - private: - base_ren_type* m_ren; - color_type m_color; - }; + //-------------------------------------------------------------------- + template void render(const Scanline& sl) + { + render_scanline_subpix_solid(sl, *m_ren, m_color); + } + private: + base_ren_type* m_ren; + color_type m_color; + }; } diff --git a/src/servers/app/drawing/Painter/agg_scanline_p_subpix.h b/src/servers/app/drawing/Painter/agg_scanline_p_subpix.h new file mode 100644 index 0000000000..a238c11719 --- /dev/null +++ b/src/servers/app/drawing/Painter/agg_scanline_p_subpix.h @@ -0,0 +1,167 @@ +/* + * Copyright 2008, Andrej Spielmann . + * All rights reserved. Distributed under the terms of the MIT License. + * + * Copyright 2002-2004 Maxim Shemanarev (http://www.antigrain.com) + * + * + * Class scanline_p8_subpix_avrg_filtering, a slightly modified version of + * scanline_p8 customized to store 3 covers per pixel + * + */ + +#ifndef AGG_SCANLINE_P_SUBPIX_INCLUDED +#define AGG_SCANLINE_P_SUBPIX_INCLUDED + +#include "agg_array.h" + +namespace agg +{ + + //======================================================scanline_p8_subpix + // + // This is a general purpose scaline container which supports the interface + // used in the rasterizer::render(). See description of scanline_u8 + // for details. + // + //------------------------------------------------------------------------ + class scanline_p8_subpix + { + public: + typedef scanline_p8_subpix self_type; + typedef int8u cover_type; + typedef int16 coord_type; + + //-------------------------------------------------------------------- + struct span + { + coord_type x; + coord_type len; // If negative, it's a solid span, covers is valid + const cover_type* covers; + }; + + typedef span* iterator; + typedef const span* const_iterator; + + scanline_p8_subpix() : + m_last_x(0x7FFFFFF0), + m_covers(), + m_cover_ptr(0), + m_spans(), + m_cur_span(0) + { + } + + //-------------------------------------------------------------------- + void reset(int min_x, int max_x) + { + unsigned max_len = 3*(max_x - min_x + 3); + if(max_len > m_spans.size()) + { + m_spans.resize(max_len); + m_covers.resize(max_len); + } + m_last_x = 0x7FFFFFF0; + m_cover_ptr = &m_covers[0]; + m_cur_span = &m_spans[0]; + m_cur_span->len = 0; + } + + //-------------------------------------------------------------------- + void add_cell(int x, unsigned cover1, unsigned cover2, unsigned cover3) + { + m_cover_ptr[0] = (cover_type)cover1; + m_cover_ptr[1] = (cover_type)cover2; + m_cover_ptr[2] = (cover_type)cover3; + if(x == m_last_x+1 && m_cur_span->len > 0) + { + m_cur_span->len += 3; + } + else + { + m_cur_span++; + m_cur_span->covers = m_cover_ptr; + m_cur_span->x = (int16)x; + m_cur_span->len = 3; + } + m_last_x = x; + m_cover_ptr += 3; + } + + //-------------------------------------------------------------------- + void add_cells(int x, unsigned len, const cover_type* covers) + { + memcpy(m_cover_ptr, covers, 3 * len * sizeof(cover_type)); + if(x == m_last_x+1 && m_cur_span->len > 0) + { + m_cur_span->len += 3 * (int16)len; + } + else + { + m_cur_span++; + m_cur_span->covers = m_cover_ptr; + m_cur_span->x = (int16)x; + m_cur_span->len = 3 * (int16)len; + } + m_cover_ptr += 3 * len; + m_last_x = x + len - 1; + } + + //-------------------------------------------------------------------- + void add_span(int x, unsigned len, unsigned cover) + { + if(x == m_last_x+1 && + m_cur_span->len < 0 && + cover == *m_cur_span->covers) + { + m_cur_span->len -= 3 * (int16)len; + } + else + { + *m_cover_ptr = (cover_type)cover; + m_cur_span++; + m_cur_span->covers = m_cover_ptr; + m_cover_ptr += 3; + m_cur_span->x = (int16)x; + m_cur_span->len = 3 * (int16)(-int(len)); + } + m_last_x = x + len - 1; + } + + //-------------------------------------------------------------------- + void finalize(int y) + { + m_y = y; + } + + //-------------------------------------------------------------------- + void reset_spans() + { + m_last_x = 0x7FFFFFF0; + m_cover_ptr = &m_covers[0]; + m_cur_span = &m_spans[0]; + m_cur_span->len = 0; + } + + //-------------------------------------------------------------------- + int y() const { return m_y; } + unsigned num_spans() const { return unsigned(m_cur_span - &m_spans[0]); } + const_iterator begin() const { return &m_spans[1]; } + + private: + scanline_p8_subpix(const self_type&); + const self_type& operator = (const self_type&); + + int m_last_x; + int m_y; + pod_array m_covers; + cover_type* m_cover_ptr; + pod_array m_spans; + span* m_cur_span; + }; + +} + + +#endif + diff --git a/src/servers/app/drawing/Painter/agg_scanline_p_subpix_avrg_filtering.h b/src/servers/app/drawing/Painter/agg_scanline_p_subpix_avrg_filtering.h new file mode 100644 index 0000000000..5ff6553c33 --- /dev/null +++ b/src/servers/app/drawing/Painter/agg_scanline_p_subpix_avrg_filtering.h @@ -0,0 +1,195 @@ +/* + * Copyright 2008, Andrej Spielmann . + * Copyright 2008, Stephan Aßmus . + * All rights reserved. Distributed under the terms of the MIT License. + * + * Copyright 2002-2004 Maxim Shemanarev (http://www.antigrain.com) + * + * + * Class scanline_p8_subpix_avrg_filtering, a slightly modified version of + * scanline_p8 customized to store 3 covers per pixel and to implement + * average-based color filtering + * + */ + +#ifndef AGG_SCANLINE_P_SUBPIX_AVRG_FILTERING_INCLUDED +#define AGG_SCANLINE_P_SUBPIX_AVRG_FILTERING_INCLUDED + +#include "GlobalSubpixelSettings.h" + +namespace agg +{ + //========================================scanline_p8_subpix_avrg_filtering + // + // This is a general purpose scaline container which supports the interface + // used in the rasterizer::render(). See description of scanline_u8 + // for details. + // + //------------------------------------------------------------------------ + class scanline_p8_subpix_avrg_filtering + { + public: + typedef scanline_p8_subpix self_type; + typedef int8u cover_type; + typedef int16 coord_type; + + //-------------------------------------------------------------------- + struct span + { + coord_type x; + coord_type len; // If negative, it's a solid span, covers is valid + const cover_type* covers; + }; + + typedef span* iterator; + typedef const span* const_iterator; + + scanline_p8_subpix_avrg_filtering() : + m_last_x(0x7FFFFFF0), + m_covers(), + m_cover_ptr(0), + m_spans(), + m_cur_span(0) + { + } + + //-------------------------------------------------------------------- + void reset(int min_x, int max_x) + { + unsigned max_len = 3*(max_x - min_x + 3); + if(max_len > m_spans.size()) + { + m_spans.resize(max_len); + m_covers.resize(max_len); + } + m_last_x = 0x7FFFFFF0; + m_cover_ptr = &m_covers[0]; + m_cur_span = &m_spans[0]; + m_cur_span->len = 0; + } + + //-------------------------------------------------------------------- + void add_cell(int x, unsigned cover1, unsigned cover2, unsigned cover3) + { + + // NOTE stippi: My basic idea is that filtering tries to minimize colored + // edges, but it does so by blurring the coverage values. This will also + // affect neighboring pixels and add blur where there were perfectly sharp + // edges. Andrej's method of filtering adds a special case for perfectly + // sharp edges, but the drawback here is that there will be a visible + // transition between blurred and non-blurred subpixels. I had the idea that + // when simply fading the subpixels towards the plain gray-scale-aa values, + // there must be a sweet spot for when colored edges become non-disturbing + // and there is still a benefit of sharpness compared to straight gray-scale- + // aa. The define above enables this method against the colored edges. My + // method still has a drawback, since jaggies in diagonal lines will be more + // visible again than with the filter method. + + unsigned char averageWeight = gSubpixelAverageWeight; + unsigned char subpixelWeight = 255 - averageWeight; + + unsigned int coverR; + unsigned int coverG; + unsigned int coverB; + + unsigned int average = (cover1 + cover2 + cover3 + 2) / 3; + + coverR = (cover1 * subpixelWeight + average * averageWeight) >> 8; + coverG = (cover2 * subpixelWeight + average * averageWeight) >> 8; + coverB = (cover3 * subpixelWeight + average * averageWeight) >> 8; + + m_cover_ptr[0] = (cover_type)coverR; + m_cover_ptr[1] = (cover_type)coverG; + m_cover_ptr[2] = (cover_type)coverB; + if(x == m_last_x+1 && m_cur_span->len > 0) + { + m_cur_span->len += 3; + } + else + { + m_cur_span++; + m_cur_span->covers = m_cover_ptr; + m_cur_span->x = (int16)x; + m_cur_span->len = 3; + } + m_last_x = x; + m_cover_ptr += 3; + } + + //-------------------------------------------------------------------- + void add_cells(int x, unsigned len, const cover_type* covers) + { + memcpy(m_cover_ptr, covers, 3 * len * sizeof(cover_type)); + if(x == m_last_x+1 && m_cur_span->len > 0) + { + m_cur_span->len += 3 * (int16)len; + } + else + { + m_cur_span++; + m_cur_span->covers = m_cover_ptr; + m_cur_span->x = (int16)x; + m_cur_span->len = 3 * (int16)len; + } + m_cover_ptr += 3 * len; + m_last_x = x + len - 1; + } + + //-------------------------------------------------------------------- + void add_span(int x, unsigned len, unsigned cover) + { + if(x == m_last_x+1 && + m_cur_span->len < 0 && + cover == *m_cur_span->covers) + { + m_cur_span->len -= 3 * (int16)len; + } + else + { + *m_cover_ptr = (cover_type)cover; + m_cur_span++; + m_cur_span->covers = m_cover_ptr; + m_cover_ptr += 3; + m_cur_span->x = (int16)x; + m_cur_span->len = 3 * (int16)(-int(len)); + } + m_last_x = x + len - 1; + } + + //-------------------------------------------------------------------- + void finalize(int y) + { + m_y = y; + } + + //-------------------------------------------------------------------- + void reset_spans() + { + m_last_x = 0x7FFFFFF0; + m_cover_ptr = &m_covers[0]; + m_cur_span = &m_spans[0]; + m_cur_span->len = 0; + } + + //-------------------------------------------------------------------- + int y() const { return m_y; } + unsigned num_spans() const { return unsigned(m_cur_span - &m_spans[0]); } + const_iterator begin() const { return &m_spans[1]; } + + private: + scanline_p8_subpix_avrg_filtering(const self_type&); + const self_type& operator = (const self_type&); + + int m_last_x; + int m_y; + pod_array m_covers; + cover_type* m_cover_ptr; + pod_array m_spans; + span* m_cur_span; + }; + +} + + +#endif + diff --git a/src/servers/app/drawing/Painter/agg_scanline_u_subpix_avrg_filtering.h b/src/servers/app/drawing/Painter/agg_scanline_u_subpix_avrg_filtering.h new file mode 100644 index 0000000000..6c4fdbfffc --- /dev/null +++ b/src/servers/app/drawing/Painter/agg_scanline_u_subpix_avrg_filtering.h @@ -0,0 +1,165 @@ +/* + * Copyright 2008, Andrej Spielmann . + * Copyright 2008, Stephan Aßmus . + * All rights reserved. Distributed under the terms of the MIT License. + * + * Copyright 2002-2004 Maxim Shemanarev (http://www.antigrain.com) + * + * + * Class scanline_u8_subpix_avrg_filtering, a slightly modified version of + * scanline_u8 customized to store 3 covers per pixel and to implement + * average-based color filtering + * + */ + +#ifndef AGG_SCANLINE_U_SUBPIX_AVRG_FILTERING_INCLUDED +#define AGG_SCANLINE_U_SUBPIX_AVRG_FILTERING_INCLUDED + +#include "GlobalSubpixelSettings.h" + +namespace agg +{ + //=======================================scanline_u8_subpix_avrg_filtering + //------------------------------------------------------------------------ + class scanline_u8_subpix_avrg_filtering + { + public: + typedef scanline_u8_subpix_avrg_filtering self_type; + typedef int8u cover_type; + typedef int16 coord_type; + + //-------------------------------------------------------------------- + struct span + { + coord_type x; + coord_type len; + cover_type* covers; + }; + + typedef span* iterator; + typedef const span* const_iterator; + + //-------------------------------------------------------------------- + scanline_u8_subpix_avrg_filtering() : + m_min_x(0), + m_last_x(0x7FFFFFF0), + m_cur_span(0) + {} + + //-------------------------------------------------------------------- + void reset(int min_x, int max_x) + { + unsigned max_len = 3*(max_x - min_x + 2); + if(max_len > m_spans.size()) + { + m_spans.resize(max_len); + m_covers.resize(max_len); + } + m_last_x = 0x7FFFFFF0; + m_min_x = min_x; + m_cur_span = &m_spans[0]; + } + + //-------------------------------------------------------------------- + void add_cell(int x, unsigned cover1, unsigned cover2, unsigned cover3) + { + + // NOTE stippi: My basic idea is that filtering tries to minimize colored + // edges, but it does so by blurring the coverage values. This will also + // affect neighboring pixels and add blur where there were perfectly sharp + // edges. Andrej's method of filtering adds a special case for perfectly + // sharp edges, but the drawback here is that there will be a visible + // transition between blurred and non-blurred subpixels. I had the idea that + // when simply fading the subpixels towards the plain gray-scale-aa values, + // there must be a sweet spot for when colored edges become non-disturbing + // and there is still a benefit of sharpness compared to straight gray-scale- + // aa. The define above enables this method against the colored edges. My + // method still has a drawback, since jaggies in diagonal lines will be more + // visible again than with the filter method. + + unsigned char averageWeight = gSubpixelAverageWeight; + unsigned char subpixelWeight = 255 - averageWeight; + + unsigned int coverR; + unsigned int coverG; + unsigned int coverB; + + unsigned int average = (cover1 + cover2 + cover3 + 2) / 3; + + coverR = (cover1 * subpixelWeight + average * averageWeight) >> 8; + coverG = (cover2 * subpixelWeight + average * averageWeight) >> 8; + coverB = (cover3 * subpixelWeight + average * averageWeight) >> 8; + + x -= m_min_x; + m_covers[3 * x] = (cover_type)coverR; + m_covers[3 * x + 1] = (cover_type)coverG; + m_covers[3 * x + 2] = (cover_type)coverB; + if(x == m_last_x + 1) + { + m_cur_span->len += 3; + } + else + { + m_cur_span++; + m_cur_span->x = (coord_type)(x + m_min_x); + m_cur_span->len = 3; + m_cur_span->covers = &m_covers[3 * x]; + } + m_last_x = x; + } + + //-------------------------------------------------------------------- + void add_span(int x, unsigned len, unsigned cover) + { + x -= m_min_x; + memset(&m_covers[3 * x], cover, 3 * len); + if(x == m_last_x+1) + { + m_cur_span->len += 3 * (coord_type)len; + } + else + { + m_cur_span++; + m_cur_span->x = (coord_type)(x + m_min_x); + m_cur_span->len = 3 * (coord_type)len; + m_cur_span->covers = &m_covers[3 * x]; + } + m_last_x = x + len - 1; + } + + //-------------------------------------------------------------------- + void finalize(int y) + { + m_y = y; + } + + //-------------------------------------------------------------------- + void reset_spans() + { + m_last_x = 0x7FFFFFF0; + m_cur_span = &m_spans[0]; + } + + //-------------------------------------------------------------------- + int y() const { return m_y; } + unsigned num_spans() const { return unsigned(m_cur_span - &m_spans[0]); } + const_iterator begin() const { return &m_spans[1]; } + iterator begin() { return &m_spans[1]; } + + private: + scanline_u8_subpix_avrg_filtering(const self_type&); + const self_type& operator = (const self_type&); + + private: + int m_min_x; + int m_last_x; + int m_y; + pod_array m_covers; + pod_array m_spans; + span* m_cur_span; + }; + +} + +#endif + diff --git a/src/servers/app/drawing/Painter/defines.h b/src/servers/app/drawing/Painter/defines.h index 0bf24f8672..f0420b0808 100644 --- a/src/servers/app/drawing/Painter/defines.h +++ b/src/servers/app/drawing/Painter/defines.h @@ -22,11 +22,18 @@ #include #include +#include "agg_rasterizer_scanline_aa_subpix.h" #include "agg_renderer_region.h" #include "agg_renderer_scanline_subpix.h" +#include "agg_scanline_p_subpix.h" +#include "agg_scanline_p_subpix_avrg_filtering.h" +#include "agg_scanline_u_subpix.h" +#include "agg_scanline_u_subpix_avrg_filtering.h" +#include "GlobalSubpixelSettings.h" #include "PixelFormat.h" + #define ALIASED_DRAWING 0 typedef PixelFormat pixfmt; @@ -45,13 +52,21 @@ typedef agg::scanline_u8 scanline_unpacked_type; typedef agg::scanline_p8 scanline_packed_type; - typedef agg::renderer_scanline_aa_solid renderer_type; +#ifdef AVERAGE_BASED_SUBPIXEL_FILTERING + typedef agg::scanline_p8_subpix_avrg_filtering scanline_packed_subpix_type; + typedef agg::scanline_u8_subpix_avrg_filtering scanline_unpacked_subpix_type; +#else + typedef agg::scanline_p8_subpix scanline_packed_subpix_type; + typedef agg::scanline_u8_subpix scanline_unpacked_subpix_type; #endif + typedef agg::renderer_scanline_aa_solid renderer_type; +#endif // !ALIASED_DRAWING typedef agg::renderer_scanline_bin_solid renderer_bin_type; typedef agg::renderer_scanline_subpix_solid renderer_subpix_type; typedef agg::rasterizer_scanline_aa<> rasterizer_type; + typedef agg::rasterizer_scanline_aa_subpix<> rasterizer_subpix_type; #endif // DEFINES_H diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAddSUBPIX.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAddSUBPIX.h index 3aea497dfc..4f6f03694f 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAddSUBPIX.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAddSUBPIX.h @@ -11,7 +11,7 @@ #define DRAWING_MODE_ADD_SUBPIX_H #include "DrawingMode.h" - +#include "GlobalSubpixelSettings.h" // BLEND_ADD_SUBPIX #define BLEND_ADD_SUBPIX(d, r, g, b, a1, a2, a3) \ @@ -25,70 +25,19 @@ } -// BLEND_ADD -#define BLEND_ADD(d, r, g, b, a) \ -{ \ - pixel32 _p; \ - _p.data32 = *(uint32*)d; \ - uint8 rt = min_c(255, _p.data8[2] + (r)); \ - uint8 gt = min_c(255, _p.data8[1] + (g)); \ - uint8 bt = min_c(255, _p.data8[0] + (b)); \ - BLEND(d, rt, gt, bt, a); \ -} - - -//ASSIGN_ADD -#define ASSIGN_ADD(d, r, g, b) \ -{ \ - pixel32 _p; \ - _p.data32 = *(uint32*)d; \ - d[0] = min_c(255, _p.data8[0] + (b)); \ - d[1] = min_c(255, _p.data8[1] + (g)); \ - d[2] = min_c(255, _p.data8[2] + (r)); \ - d[3] = 255; \ -} - - -// blend_hline_add_subpix -void -blend_hline_add_subpix(int x, int y, unsigned len, const color_type& c, - uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) -{ - uint8* p = buffer->row_ptr(y) + (x << 2); - if (cover == 255) { - do { - rgb_color color = pattern->ColorAt(x, y); - - ASSIGN_ADD(p, color.red, color.green, color.blue); - - p += 4; - x++; - len -= 3; - } while (len); - } else { - do { - rgb_color color = pattern->ColorAt(x, y); - - BLEND_ADD(p, color.red, color.green, color.blue, cover); - - x++; - p += 4; - len -= 3; - } while (len); - } -} - - // blend_solid_hspan_add_subpix void blend_solid_hspan_add_subpix(int x, int y, unsigned len, const color_type& c, const uint8* covers, agg_buffer* buffer, const PatternHandler* pattern) { + const int subpixelL = gSubpixelOrderingRGB ? 2 : 0; + const int subpixelM = 1; + const int subpixelR = gSubpixelOrderingRGB ? 0 : 2; uint8* p = buffer->row_ptr(y) + (x << 2); do { rgb_color color = pattern->ColorAt(x, y); BLEND_ADD_SUBPIX(p, color.red, color.green, color.blue, - covers[2], covers[1], covers[0]); + covers[subpixelL], covers[subpixelM], covers[subpixelR]); covers += 3; p += 4; x++; diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaCCSUBPIX.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaCCSUBPIX.h index 57af38f3c9..fe46a019c7 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaCCSUBPIX.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaCCSUBPIX.h @@ -11,6 +11,7 @@ #define DRAWING_MODE_ALPHA_CC_SUBPIX_H #include "DrawingMode.h" +#include "GlobalSubpixelSettings.h" // BLEND_ALPHA_CC_SUBPIX #define BLEND_ALPHA_CC_SUBPIX(d, r, g, b, a1, a2, a3) \ @@ -19,71 +20,6 @@ } -// BLEND_ALPHA_CC -#define BLEND_ALPHA_CC(d, r, g, b, a) \ -{ \ - BLEND_COMPOSITE16(d, r, g, b, a); \ -} - - -// ASSIGN_ALPHA_CC -#define ASSIGN_ALPHA_CC(d, r, g, b) \ -{ \ - d[0] = (b); \ - d[1] = (g); \ - d[2] = (r); \ - d[3] = 255; \ -} - - -// blend_hline_alpha_cc_subpix -void -blend_hline_alpha_cc_subpix(int x, int y, unsigned len, const color_type& c, - uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) -{ - rgb_color color = pattern->HighColor(); - uint16 alpha = color.alpha * cover; - if (alpha == 255 * 255) { - // cache the low and high color as 32bit values - // high color - uint32 vh; - uint8* p8 = (uint8*)&vh; - p8[0] = color.blue; - p8[1] = color.green; - p8[2] = color.red; - p8[3] = 255; - // low color - color = pattern->LowColor(); - uint32 vl; - p8 = (uint8*)&vl; - p8[0] = color.blue; - p8[1] = color.green; - p8[2] = color.red; - p8[3] = 255; - // row offset as 32 bit pointer - uint32* p32 = (uint32*)(buffer->row_ptr(y)) + x; - do { - if (pattern->IsHighColor(x, y)) - *p32 = vh; - else - *p32 = vl; - p32++; - x++; - len -= 3; - } while (len); - } else { - uint8* p = buffer->row_ptr(y) + (x << 2); - do { - rgb_color color = pattern->ColorAt(x, y); - BLEND_ALPHA_CC(p, color.red, color.green, color.blue, alpha); - x++; - p += 4; - len -= 3; - } while (len); - } -} - - // blend_solid_hspan_alpha_cc_subpix void blend_solid_hspan_alpha_cc_subpix(int x, int y, unsigned len, @@ -95,13 +31,16 @@ blend_solid_hspan_alpha_cc_subpix(int x, int y, unsigned len, uint16 alphaRed; uint16 alphaGreen; uint16 alphaBlue; + const int subpixelL = gSubpixelOrderingRGB ? 2 : 0; + const int subpixelM = 1; + const int subpixelR = gSubpixelOrderingRGB ? 0 : 2; do { - alphaRed = hAlpha * covers[0]; - alphaGreen = hAlpha * covers[1]; - alphaBlue = hAlpha * covers[2]; + alphaRed = hAlpha * covers[subpixelL]; + alphaGreen = hAlpha * covers[subpixelM]; + alphaBlue = hAlpha * covers[subpixelR]; rgb_color color = pattern->ColorAt(x, y); BLEND_ALPHA_CC_SUBPIX(p, color.red, color.green, color.blue, - alphaBlue,alphaGreen, alphaRed); + alphaBlue, alphaGreen, alphaRed); covers += 3; p += 4; x++; diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaCOSUBPIX.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaCOSUBPIX.h index e2d6f81f14..817e0ab7e5 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaCOSUBPIX.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaCOSUBPIX.h @@ -11,6 +11,7 @@ #define DRAWING_MODE_ALPHA_CO_SUBPIX_H #include "DrawingMode.h" +#include "GlobalSubpixelSettings.h" // BLEND_ALPHA_CO_SUBPIX #define BLEND_ALPHA_CO_SUBPIX(d, r, g, b, a1, a2, a3) \ @@ -19,71 +20,6 @@ } -// BLEND_ALPHA_CO -#define BLEND_ALPHA_CO(d, r, g, b, a) \ -{ \ - BLEND16(d, r, g, b, a); \ -} - - -// ASSIGN_ALPHA_CO -#define ASSIGN_ALPHA_CO(d, r, g, b) \ -{ \ - d[0] = (b); \ - d[1] = (g); \ - d[2] = (r); \ - d[3] = 255; \ -} - - -// blend_hline_alpha_co_subpix -void -blend_hline_alpha_co_subpix(int x, int y, unsigned len, const color_type& c, - uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) -{ - rgb_color color = pattern->HighColor(); - uint16 alpha = color.alpha * cover; - if (alpha == 255 * 255) { - // cache the low and high color as 32bit values - // high color - uint32 vh; - uint8* p8 = (uint8*)&vh; - p8[0] = color.blue; - p8[1] = color.green; - p8[2] = color.red; - p8[3] = 255; - // low color - color = pattern->LowColor(); - uint32 vl; - p8 = (uint8*)&vl; - p8[0] = color.blue; - p8[1] = color.green; - p8[2] = color.red; - p8[3] = 255; - // row offset as 32bit pointer - uint32* p32 = (uint32*)(buffer->row_ptr(y)) + x; - do { - if (pattern->IsHighColor(x, y)) - *p32 = vh; - else - *p32 = vl; - p32++; - x++; - len -= 3; - } while (len); - } else { - uint8* p = buffer->row_ptr(y) + (x << 2); - do { - rgb_color color = pattern->ColorAt(x, y); - BLEND_ALPHA_CO(p, color.red, color.green, color.blue, alpha); - x++; - p += 4; - len -= 3; - } while (len); - } -} - - // blend_solid_hspan_alpha_co_subpix void blend_solid_hspan_alpha_co_subpix(int x, int y, unsigned len, @@ -95,10 +31,13 @@ blend_solid_hspan_alpha_co_subpix(int x, int y, unsigned len, uint16 alphaRed; uint16 alphaGreen; uint16 alphaBlue; + const int subpixelL = gSubpixelOrderingRGB ? 2 : 0; + const int subpixelM = 1; + const int subpixelR = gSubpixelOrderingRGB ? 0 : 2; do { - alphaRed = hAlpha * covers[0]; - alphaGreen = hAlpha * covers[1]; - alphaBlue = hAlpha * covers[2]; + alphaRed = hAlpha * covers[subpixelL]; + alphaGreen = hAlpha * covers[subpixelM]; + alphaBlue = hAlpha * covers[subpixelR]; rgb_color color = pattern->ColorAt(x, y); BLEND_ALPHA_CO_SUBPIX(p, color.red, color.green, color.blue, alphaBlue, alphaGreen, alphaRed); diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaCOSolidSUBPIX.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaCOSolidSUBPIX.h index ffb077c971..7cfe182072 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaCOSolidSUBPIX.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaCOSolidSUBPIX.h @@ -11,45 +11,7 @@ #define DRAWING_MODE_ALPHA_CO_SOLID_SUBPIX_H #include "DrawingModeAlphaCOSUBPIX.h" - -// blend_hline_alpha_co_solid_subpix -void -blend_hline_alpha_co_solid_subpix(int x, int y, unsigned len, - const color_type& c, uint8 cover, agg_buffer* buffer, - const PatternHandler* pattern) -{ - uint16 alpha = pattern->HighColor().alpha * cover; - if (alpha == 255 * 255) { - // cache the color as 32bit values - uint32 v; - uint8* p8 = (uint8*)&v; - p8[0] = c.b; - p8[1] = c.g; - p8[2] = c.r; - p8[3] = 255; - // row offset as 32bit pointer - uint32* p32 = (uint32*)(buffer->row_ptr(y)) + x; - do { - *p32 = v; - p32++; - x++; - len -= 3; - } while (len); - } else { - uint8* p = buffer->row_ptr(y) + (x << 2); - if (len < 12) { - do { - BLEND_ALPHA_CO(p, c.r, c.g, c.b, alpha); - x++; - p += 4; - len -= 3; - } while (len); - } else { - alpha = alpha >> 8; - blend_line32(p, len / 3, c.r, c.g, c.b, alpha); - } - } -} +#include "GlobalSubpixelSettings.h" // blend_solid_hspan_alpha_co_solid_subpix @@ -63,10 +25,13 @@ blend_solid_hspan_alpha_co_solid_subpix(int x, int y, unsigned len, uint16 alphaRed; uint16 alphaGreen; uint16 alphaBlue; + const int subpixelL = gSubpixelOrderingRGB ? 2 : 0; + const int subpixelM = 1; + const int subpixelR = gSubpixelOrderingRGB ? 0 : 2; do { - alphaRed = hAlpha * covers[0]; - alphaGreen = hAlpha * covers[1]; - alphaBlue = hAlpha * covers[2]; + alphaRed = hAlpha * covers[subpixelL]; + alphaGreen = hAlpha * covers[subpixelM]; + alphaBlue = hAlpha * covers[subpixelR]; BLEND_ALPHA_CO_SUBPIX(p, c.r, c.g, c.b, alphaBlue, alphaGreen, alphaRed); covers += 3; diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPCSUBPIX.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPCSUBPIX.h index 17ac7b80ac..88ebb25ed5 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPCSUBPIX.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPCSUBPIX.h @@ -11,6 +11,7 @@ #define DRAWING_MODE_ALPHA_PC_SUBPIX_H #include "DrawingMode.h" +#include "GlobalSubpixelSettings.h" // BLEND_ALPHA_PC_SUBPIX #define BLEND_ALPHA_PC_SUBPIX(d, r, g, b, a1, a2, a3) \ @@ -19,46 +20,6 @@ } -// BLEND_ALPHA_PC -#define BLEND_ALPHA_PC(d, r, g, b, a) \ -{ \ - BLEND_COMPOSITE16(d, r, g, b, a); \ -} - - -// ASSIGN_ALPHA_PC -#define ASSIGN_ALPHA_PC(d, r, g, b) \ -{ \ - d[0] = (b); \ - d[1] = (g); \ - d[2] = (r); \ - d[3] = 255; \ -} - - -// blend_hline_alpha_pc_subpix -void -blend_hline_alpha_pc_subpix(int x, int y, unsigned len, const color_type& c, - uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) -{ - uint8* p = buffer->row_ptr(y) + (x << 2); - do { - rgb_color color = pattern->ColorAt(x, y); - uint16 alpha = color.alpha * cover; - if (alpha) { - if (alpha == 255) { - ASSIGN_ALPHA_PC(p, color.red, color.green, color.blue); - } else { - BLEND_ALPHA_PC(p, color.red, color.green, color.blue, alpha); - } - } - x++; - p += 4; - len -= 3; - } while (len); -} - - // blend_solid_hspan_alpha_pc_subpix void blend_solid_hspan_alpha_pc_subpix(int x, int y, unsigned len, @@ -69,11 +30,14 @@ blend_solid_hspan_alpha_pc_subpix(int x, int y, unsigned len, uint16 alphaRed; uint16 alphaGreen; uint16 alphaBlue; + const int subpixelL = gSubpixelOrderingRGB ? 2 : 0; + const int subpixelM = 1; + const int subpixelR = gSubpixelOrderingRGB ? 0 : 2; do { rgb_color color = pattern->ColorAt(x, y); - alphaRed = color.alpha * covers[0]; - alphaGreen = color.alpha * covers[1]; - alphaBlue = color.alpha * covers[2]; + alphaRed = color.alpha * covers[subpixelL]; + alphaGreen = color.alpha * covers[subpixelM]; + alphaBlue = color.alpha * covers[subpixelR]; BLEND_ALPHA_PC_SUBPIX(p, color.red, color.green, color.blue, alphaBlue, alphaGreen, alphaRed); covers += 3; diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPOSUBPIX.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPOSUBPIX.h index 1c0cc1b4b0..7cc0b1c509 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPOSUBPIX.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPOSUBPIX.h @@ -11,6 +11,7 @@ #define DRAWING_MODE_ALPHA_PO_SUBPIX_H #include "DrawingMode.h" +#include "GlobalSubpixelSettings.h" // BLEND_ALPHA_PO_SUBPIX #define BLEND_ALPHA_PO_SUBPIX(d, r, g, b, a1, a2, a3) \ @@ -18,44 +19,6 @@ BLEND16_SUBPIX(d, r, g, b, a1, a2, a3); \ } -// BLEND_ALPHA_PO -#define BLEND_ALPHA_PO(d, r, g, b, a) \ -{ \ - BLEND16(d, r, g, b, a); \ -} - -// ASSIGN_ALPHA_PO -#define ASSIGN_ALPHA_PO(d, r, g, b) \ -{ \ - d[0] = (b); \ - d[1] = (g); \ - d[2] = (r); \ - d[3] = 255; \ -} - - -// blend_hline_alpha_po_subpix -void -blend_hline_alpha_po_subpix(int x, int y, unsigned len, const color_type& c, - uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) -{ - uint8* p = buffer->row_ptr(y) + (x << 2); - do { - rgb_color color = pattern->ColorAt(x, y); - uint16 alpha = color.alpha * cover; - if (alpha) { - if (alpha == 255) { - ASSIGN_ALPHA_PO(p, color.red, color.green, color.blue); - } else { - BLEND_ALPHA_PO(p, color.red, color.green, color.blue, alpha); - } - } - x++; - p += 4; - len -= 3; - } while(len); -} - // blend_solid_hspan_alpha_po_subpix void @@ -67,11 +30,14 @@ blend_solid_hspan_alpha_po_subpix(int x, int y, unsigned len, uint16 alphaRed; uint16 alphaGreen; uint16 alphaBlue; + const int subpixelL = gSubpixelOrderingRGB ? 2 : 0; + const int subpixelM = 1; + const int subpixelR = gSubpixelOrderingRGB ? 0 : 2; do { rgb_color color = pattern->ColorAt(x, y); - alphaRed = color.alpha * covers[0]; - alphaGreen = color.alpha * covers[1]; - alphaBlue = color.alpha * covers[2]; + alphaRed = color.alpha * covers[subpixelL]; + alphaGreen = color.alpha * covers[subpixelM]; + alphaBlue = color.alpha * covers[subpixelR]; BLEND_ALPHA_PO_SUBPIX(p, color.red, color.green, color.blue, alphaBlue, alphaGreen, alphaRed); covers += 3; diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPOSolidSUBPIX.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPOSolidSUBPIX.h index 2bb5e8317f..e52632737c 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPOSolidSUBPIX.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPOSolidSUBPIX.h @@ -11,46 +11,7 @@ #define DRAWING_MODE_ALPHA_PO_SOLID_SUBPIX_H #include "DrawingModeAlphaPOSUBPIX.h" - -// blend_hline_alpha_po_solid_subpix -void -blend_hline_alpha_po_solid_subpix(int x, int y, unsigned len, - const color_type& c, uint8 cover, agg_buffer* buffer, - const PatternHandler* pattern) -{ - uint16 alpha = c.a * cover; - if (alpha == 255 * 255) { - // cache the color as 32bit values - uint32 v; - uint8* p8 = (uint8*)&v; - p8[0] = c.b; - p8[1] = c.g; - p8[2] = c.r; - p8[3] = 255; - // row offset as 32bit pointer - uint32* p32 = (uint32*)(buffer->row_ptr(y)) + x; - do { - *p32 = v; - p32++; - x++; - len -= 3; - } while (len); - } else { - uint8* p = buffer->row_ptr(y) + (x << 2); - if (len < 12) { - do { - BLEND_ALPHA_CO(p, c.r, c.g, c.b, alpha); - x++; - p += 4; - len -= 3; - } while (len); - } else { - alpha = alpha >> 8; - blend_line32(p, len / 3, c.r, c.g, c.b, alpha); - } - } -} - +#include "GlobalSubpixelSettings.h" // blend_solid_hspan_alpha_po_solid_subpix void @@ -62,10 +23,13 @@ blend_solid_hspan_alpha_po_solid_subpix(int x, int y, unsigned len, uint16 alphaRed; uint16 alphaGreen; uint16 alphaBlue; + const int subpixelL = gSubpixelOrderingRGB ? 2 : 0; + const int subpixelM = 1; + const int subpixelR = gSubpixelOrderingRGB ? 0 : 2; do { - alphaRed = c.a * covers[0]; - alphaGreen = c.a * covers[1]; - alphaBlue = c.a * covers[2]; + alphaRed = c.a * covers[subpixelL]; + alphaGreen = c.a * covers[subpixelM]; + alphaBlue = c.a * covers[subpixelR]; BLEND_ALPHA_PO_SUBPIX(p, c.r, c.g, c.b, alphaBlue, alphaGreen, alphaRed); covers += 3; diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeBlendSUBPIX.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeBlendSUBPIX.h index 5cd16e0937..e0270e843a 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeBlendSUBPIX.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeBlendSUBPIX.h @@ -11,6 +11,7 @@ #define DRAWING_MODE_BLEND_SUBPIX_H #include "DrawingMode.h" +#include "GlobalSubpixelSettings.h" // BLEND_BLEND_SUBPIX @@ -25,70 +26,19 @@ } -// BLEND_BLEND -#define BLEND_BLEND(d, r, g, b, a) \ -{ \ - pixel32 _p; \ - _p.data32 = *(uint32*)d; \ - uint8 bt = (_p.data8[0] + (b)) >> 1; \ - uint8 gt = (_p.data8[1] + (g)) >> 1; \ - uint8 rt = (_p.data8[2] + (r)) >> 1; \ - BLEND(d, rt, gt, bt, a); \ -} - - -// ASSIGN_BLEND -#define ASSIGN_BLEND(d, r, g, b) \ -{ \ - pixel32 _p; \ - _p.data32 = *(uint32*)d; \ - d[0] = (_p.data8[0] + (b)) >> 1; \ - d[1] = (_p.data8[1] + (g)) >> 1; \ - d[2] = (_p.data8[2] + (r)) >> 1; \ - d[3] = 255; \ -} - - -// blend_hline_blend_subpix -void -blend_hline_blend_subpix(int x, int y, unsigned len, const color_type& c, - uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) -{ - uint8* p = buffer->row_ptr(y) + (x << 2); - if (cover == 255) { - do { - rgb_color color = pattern->ColorAt(x, y); - - ASSIGN_BLEND(p, color.red, color.green, color.blue); - - p += 4; - x++; - len -= 3; - } while (len); - } else { - do { - rgb_color color = pattern->ColorAt(x, y); - - BLEND_BLEND(p, color.red, color.green, color.blue, cover); - - p += 4; - x++; - len -= 3; - } while (len); - } -} - - // blend_solid_hspan_blend_subpix void blend_solid_hspan_blend_subpix(int x, int y, unsigned len, const color_type& c, const uint8* covers, agg_buffer* buffer, const PatternHandler* pattern) { uint8* p = buffer->row_ptr(y) + (x << 2); + const int subpixelL = gSubpixelOrderingRGB ? 2 : 0; + const int subpixelM = 1; + const int subpixelR = gSubpixelOrderingRGB ? 0 : 2; do { rgb_color color = pattern->ColorAt(x, y); BLEND_BLEND_SUBPIX(p, color.red, color.green, color.blue, - covers[2], covers[1], covers[0]); + covers[subpixelL], covers[subpixelM], covers[subpixelR]); covers += 3; p += 4; x++; diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeCopySUBPIX.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeCopySUBPIX.h index 5242a5ece4..a76691292d 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeCopySUBPIX.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeCopySUBPIX.h @@ -11,6 +11,7 @@ #define DRAWING_MODE_COPY_SUBPIX_H #include "DrawingMode.h" +#include "GlobalSubpixelSettings.h" // BLEND_COPY_SUBPIX #define BLEND_COPY_SUBPIX(d, r2, g2, b2, a1, a2, a3, r1, g1, b1) \ @@ -19,72 +20,6 @@ } -// BLEND_COPY -#define BLEND_COPY(d, r2, g2, b2, a, r1, g1, b1) \ -{ \ - BLEND_FROM(d, r1, g1, b1, r2, g2, b2, a); \ -} - - -// ASSIGN_COPY -#define ASSIGN_COPY(d, r, g, b, a) \ -{ \ - d[0] = (b); \ - d[1] = (g); \ - d[2] = (r); \ - d[3] = (a); \ -} - - -// blend_hline_copy_subpix -void -blend_hline_copy_subpix(int x, int y, unsigned len, const color_type& c, - uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) -{ - if (cover == 255) { - // cache the low and high color as 32bit values - // high color - rgb_color color = pattern->HighColor(); - uint32 vh; - uint8* p8 = (uint8*)&vh; - p8[0] = (uint8)color.blue; - p8[1] = (uint8)color.green; - p8[2] = (uint8)color.red; - p8[3] = 255; - // low color - color = pattern->LowColor(); - uint32 vl; - p8 = (uint8*)&vl; - p8[0] = (uint8)color.blue; - p8[1] = (uint8)color.green; - p8[2] = (uint8)color.red; - p8[3] = 255; - // row offset as 32bit pointer - uint32* p32 = (uint32*)(buffer->row_ptr(y)) + x; - do { - if (pattern->IsHighColor(x, y)) - *p32 = vh; - else - *p32 = vl; - p32++; - x++; - len -= 3; - } while (len); - } else { - uint8* p = buffer->row_ptr(y) + (x << 2); - rgb_color l = pattern->LowColor(); - do { - rgb_color color = pattern->ColorAt(x, y); - BLEND_COPY(p, color.red, color.green, color.blue, cover, - l.red, l.green, l.blue); - x++; - p += 4; - len -= 3; - } while (len); - } -} - - // blend_solid_hspan_copy_subpix void blend_solid_hspan_copy_subpix(int x, int y, unsigned len, const color_type& c, @@ -92,10 +27,14 @@ blend_solid_hspan_copy_subpix(int x, int y, unsigned len, const color_type& c, { uint8* p = buffer->row_ptr(y) + (x << 2); rgb_color l = pattern->LowColor(); + const int subpixelL = gSubpixelOrderingRGB ? 2 : 0; + const int subpixelM = 1; + const int subpixelR = gSubpixelOrderingRGB ? 0 : 2; do { rgb_color color = pattern->ColorAt(x, y); BLEND_COPY_SUBPIX(p, color.red, color.green, color.blue, - covers[2], covers[1], covers[0], l.red, l.green, l.blue); + covers[subpixelL], covers[subpixelM], covers[subpixelR], l.red, + l.green, l.blue); covers += 3; p += 4; x++; diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeCopySolidSUBPIX.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeCopySolidSUBPIX.h index 5e2a65c1d8..28c7c21df7 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeCopySolidSUBPIX.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeCopySolidSUBPIX.h @@ -11,36 +11,7 @@ #define DRAWING_MODE_COPY_SOLID_SUBPIX_H #include "DrawingModeOverSUBPIX.h" - -// blend_hline_copy_solid_subpix -void -blend_hline_copy_solid_subpix(int x, int y, unsigned len, const color_type& c, - uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) -{ - if (cover == 255) { - uint32 v; - uint8* p8 = (uint8*)&v; - p8[0] = (uint8)c.b; - p8[1] = (uint8)c.g; - p8[2] = (uint8)c.r; - p8[3] = 255; - uint32* p32 = (uint32*)(buffer->row_ptr(y)) + x; - do { - *p32 = v; - p32++; - x++; - len -= 3; - } while (len); - } else { - uint8* p = buffer->row_ptr(y) + (x << 2); - do { - BLEND_OVER(p, c.r, c.g, c.b, cover); - x++; - p += 4; - len -= 3; - } while (len); - } -} +#include "GlobalSubpixelSettings.h" // blend_solid_hspan_copy_solid_subpix @@ -50,8 +21,12 @@ blend_solid_hspan_copy_solid_subpix(int x, int y, unsigned len, const PatternHandler* pattern) { uint8* p = buffer->row_ptr(y) + (x << 2); + const int subpixelL = gSubpixelOrderingRGB ? 2 : 0; + const int subpixelM = 1; + const int subpixelR = gSubpixelOrderingRGB ? 0 : 2; do { - BLEND_OVER_SUBPIX(p, c.r, c.g, c.b, covers[2], covers[1], covers[0]); + BLEND_OVER_SUBPIX(p, c.r, c.g, c.b, covers[subpixelL], + covers[subpixelM], covers[subpixelR]); covers += 3; p += 4; x++; diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeCopyTextSUBPIX.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeCopyTextSUBPIX.h index 3a458497b9..a0e04d6adc 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeCopyTextSUBPIX.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeCopyTextSUBPIX.h @@ -11,38 +11,7 @@ #define DRAWING_MODE_COPY_TEXT_SUBPIX_H #include "DrawingModeCopySUBPIX.h" - -// blend_hline_copy_text_subpix -void -blend_hline_copy_text_subpix(int x, int y, unsigned len, const color_type& c, - uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) -{ - if (cover == 255) { - // cache the color as 32bit value - uint32 v; - uint8* p8 = (uint8*)&v; - p8[0] = (uint8)c.b; - p8[1] = (uint8)c.g; - p8[2] = (uint8)c.r; - p8[3] = 255; - // row offset as 32bit pointer - uint32* p32 = (uint32*)(buffer->row_ptr(y)) + x; - do { - *p32 = v; - p32++; - len -= 3; - } while(len); - } else { - uint8* p = buffer->row_ptr(y) + (x << 2); - rgb_color l = pattern->LowColor(); - do { - BLEND_COPY(p, c.r, c.g, c.b, cover, l.red, l.green, l.blue); - p += 4; - len -= 3; - } while (len); - } -} - +#include "GlobalSubpixelSettings.h" // blend_solid_hspan_copy_text_subpix void @@ -52,9 +21,13 @@ blend_solid_hspan_copy_text_subpix(int x, int y, unsigned len, { //printf("blend_solid_hspan_copy_text(%d, %d)\n", x, len); uint8* p = buffer->row_ptr(y) + (x << 2); - //rgb_color l = pattern->LowColor(); + rgb_color l = pattern->LowColor(); + const int subpixelL = gSubpixelOrderingRGB ? 2 : 0; + const int subpixelM = 1; + const int subpixelR = gSubpixelOrderingRGB ? 0 : 2; do { - BLEND_OVER_SUBPIX(p, c.r, c.g, c.b, covers[2], covers[1], covers[0]); + BLEND_COPY_SUBPIX(p, c.r, c.g, c.b, covers[subpixelL], + covers[subpixelM], covers[subpixelR], l.red, l.green, l.blue); covers += 3; p += 4; x++; diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeEraseSUBPIX.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeEraseSUBPIX.h index 6550295fef..da05371095 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeEraseSUBPIX.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeEraseSUBPIX.h @@ -11,6 +11,7 @@ #define DRAWING_MODE_ERASE_SUBPIX_H #include "DrawingMode.h" +#include "GlobalSubpixelSettings.h" // BLEND_ERASE_SUBPIX #define BLEND_ERASE_SUBPIX(d, r, g, b, a1, a2, a3) \ @@ -19,58 +20,6 @@ } -// BLEND_ERASE -#define BLEND_ERASE(d, r, g, b, a) \ -{ \ - BLEND(d, r, g, b, a); \ -} - - -// ASSIGN_ERASE -#define ASSIGN_ERASE(d, r, g, b) \ -{ \ - d[0] = (b); \ - d[1] = (g); \ - d[2] = (r); \ - d[3] = 255; \ -} - - -// blend_hline_erase_subpix -void -blend_hline_erase_subpix(int x, int y, unsigned len, const color_type& c, - uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) -{ - if (cover == 255) { - rgb_color color = pattern->LowColor(); - uint32 v; - uint8* p8 = (uint8*)&v; - p8[0] = (uint8)color.blue; - p8[1] = (uint8)color.green; - p8[2] = (uint8)color.red; - p8[3] = 255; - uint32* p32 = (uint32*)(buffer->row_ptr(y)) + x; - do { - if (pattern->IsHighColor(x, y)) - *p32 = v; - p32++; - x +=3; - len -= 3; - } while (len); - } else { - uint8* p = buffer->row_ptr(y) + (x << 2); - rgb_color color = pattern->LowColor(); - do { - if (pattern->IsHighColor(x, y)) - BLEND_ERASE(p, color.red, color.green, color.blue, cover); - x++; - p += 4; - len -= 3; - } while (len); - } -} - - // blend_solid_hspan_erase_subpix void blend_solid_hspan_erase_subpix(int x, int y, unsigned len, const color_type& c, @@ -78,10 +27,13 @@ blend_solid_hspan_erase_subpix(int x, int y, unsigned len, const color_type& c, { uint8* p = buffer->row_ptr(y) + (x << 2); rgb_color color = pattern->LowColor(); + const int subpixelL = gSubpixelOrderingRGB ? 2 : 0; + const int subpixelM = 1; + const int subpixelR = gSubpixelOrderingRGB ? 0 : 2; do { if (pattern->IsHighColor(x, y)) { BLEND_ERASE_SUBPIX(p, color.red, color.green, color.blue, - covers[2], covers[1], covers[0]); + covers[subpixelL], covers[subpixelM], covers[subpixelR]); } covers += 3; p += 4; diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeInvertSUBPIX.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeInvertSUBPIX.h index 4f86a9a45c..4a548eec97 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeInvertSUBPIX.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeInvertSUBPIX.h @@ -11,6 +11,7 @@ #define DRAWING_MODE_INVERT_SUBPIX_H #include "DrawingMode.h" +#include "GlobalSubpixelSettings.h" // BLEND_INVERT_SUBPIX #define BLEND_INVERT_SUBPIX(d, a1, a2, a3) \ @@ -22,64 +23,20 @@ } -// BLEND_INVERT -#define BLEND_INVERT(d, a) \ -{ \ - pixel32 _p; \ - _p.data32 = *(uint32*)d; \ - BLEND(d, 255 - _p.data8[2], 255 - _p.data8[1], 255 - _p.data8[0], a); \ -} - - -// ASSIGN_INVERT -#define ASSIGN_INVERT(d) \ -{ \ - pixel32 _p; \ - _p.data32 = *(uint32*)d; \ - d[0] = 255 - _p.data8[0]; \ - d[1] = 255 - _p.data8[1]; \ - d[2] = 255 - _p.data8[2]; \ - d[3] = 255; \ -} - - -// blend_hline_invert_subpix -void -blend_hline_invert_subpix(int x, int y, unsigned len, const color_type& c, - uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) -{ - uint8* p = buffer->row_ptr(y) + (x << 2); - if(cover == 255) { - do { - if (pattern->IsHighColor(x, y)) { - ASSIGN_INVERT(p); - } - x++; - p += 4; - len -= 3; - } while (len); - } else { - do { - if (pattern->IsHighColor(x, y)) { - BLEND_INVERT(p, cover); - } - x++; - p += 4; - len -= 3; - } while (len); - } -} - - // blend_solid_hspan_invert_subpix void blend_solid_hspan_invert_subpix(int x, int y, unsigned len, const color_type& c, const uint8* covers, agg_buffer* buffer, const PatternHandler* pattern) { uint8* p = buffer->row_ptr(y) + (x << 2); + const int subpixelL = gSubpixelOrderingRGB ? 2 : 0; + const int subpixelM = 1; + const int subpixelR = gSubpixelOrderingRGB ? 0 : 2; do { - if (pattern->IsHighColor(x, y)) - BLEND_INVERT_SUBPIX(p, covers[2], covers[1], covers[0]); + if (pattern->IsHighColor(x, y)) { + BLEND_INVERT_SUBPIX(p, covers[subpixelL], covers[subpixelM], + covers[subpixelR]); + } covers += 3; p += 4; x++; diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeMaxSUBPIX.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeMaxSUBPIX.h index d25d6d5f72..f6c8b1d1b4 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeMaxSUBPIX.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeMaxSUBPIX.h @@ -11,6 +11,7 @@ #define DRAWING_MODE_MAX_SUBPIX_H #include "DrawingMode.h" +#include "GlobalSubpixelSettings.h" // BLEND_MAX_SUBPIX #define BLEND_MAX_SUBPIX(d, r, g, b, a1, a2, a3) \ @@ -24,73 +25,19 @@ } -// BLEND_MAX -#define BLEND_MAX(d, r, g, b, a) \ -{ \ - pixel32 _p; \ - _p.data32 = *(uint32*)d; \ - if (brightness_for((r), (g), (b)) \ - > brightness_for(_p.data8[2], _p.data8[1], _p.data8[0])) { \ - BLEND(d, (r), (g), (b), a); \ - } \ -} - - -// ASSIGN_MAX -#define ASSIGN_MAX(d, r, g, b) \ -{ \ - pixel32 _p; \ - _p.data32 = *(uint32*)d; \ - if (brightness_for((r), (g), (b)) \ - > brightness_for(_p.data8[2], _p.data8[1], _p.data8[0])) { \ - d[0] = (b); \ - d[1] = (g); \ - d[2] = (r); \ - d[3] = 255; \ - } \ -} - - -// blend_hline_max_subpix -void -blend_hline_max_subpix(int x, int y, unsigned len, const color_type& c, - uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) -{ - uint8* p = buffer->row_ptr(y) + (x << 2); - if (cover == 255) { - do { - rgb_color color = pattern->ColorAt(x, y); - - ASSIGN_MAX(p, color.red, color.green, color.blue); - - p += 4; - x++; - len -= 3; - } while (len); - } else { - do { - rgb_color color = pattern->ColorAt(x, y); - - BLEND_MAX(p, color.red, color.green, color.blue, cover); - - x++; - p += 4; - len -= 3; - } while (len); - } -} - - // blend_solid_hspan_max_subpix void blend_solid_hspan_max_subpix(int x, int y, unsigned len, const color_type& c, const uint8* covers, agg_buffer* buffer, const PatternHandler* pattern) { uint8* p = buffer->row_ptr(y) + (x << 2); + const int subpixelL = gSubpixelOrderingRGB ? 2 : 0; + const int subpixelM = 1; + const int subpixelR = gSubpixelOrderingRGB ? 0 : 2; do { rgb_color color = pattern->ColorAt(x, y); BLEND_MAX_SUBPIX(p, color.red, color.green, color.blue, - covers[2], covers[1], covers[0]); + covers[subpixelL], covers[subpixelM], covers[subpixelR]); covers += 3; p += 4; x++; diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeMinSUBPIX.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeMinSUBPIX.h index b258e1fb70..58172be41d 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeMinSUBPIX.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeMinSUBPIX.h @@ -11,6 +11,7 @@ #define DRAWING_MODE_MIN_SUBPIX_H #include "DrawingMode.h" +#include "GlobalSubpixelSettings.h" // BLEND_MIN_SUBPIX #define BLEND_MIN_SUBPIX(d, r, g, b, a1, a2, a3) \ @@ -24,73 +25,19 @@ } -// BLEND_MIN -#define BLEND_MIN(d, r, g, b, a) \ -{ \ - pixel32 _p; \ - _p.data32 = *(uint32*)d; \ - if (brightness_for((r), (g), (b)) \ - < brightness_for(_p.data8[2], _p.data8[1], _p.data8[0])) { \ - BLEND(d, (r), (g), (b), a); \ - } \ -} - - -// ASSIGN_MIN -#define ASSIGN_MIN(d, r, g, b) \ -{ \ - pixel32 _p; \ - _p.data32 = *(uint32*)d; \ - if (brightness_for((r), (g), (b)) \ - < brightness_for(_p.data8[2], _p.data8[1], _p.data8[0])) { \ - d[0] = (b); \ - d[1] = (g); \ - d[2] = (r); \ - d[3] = 255; \ - } \ -} - - -// blend_hline_min_subpix -void -blend_hline_min_subpix(int x, int y, unsigned len, const color_type& c, - uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) -{ - uint8* p = buffer->row_ptr(y) + (x << 2); - if (cover == 255) { - do { - rgb_color color = pattern->ColorAt(x, y); - - ASSIGN_MIN(p, color.red, color.green, color.blue); - - p += 4; - x++; - len -= 3; - } while (len); - } else { - do { - rgb_color color = pattern->ColorAt(x, y); - - BLEND_MIN(p, color.red, color.green, color.blue, cover); - - x++; - p += 4; - len -= 3; - } while (len); - } -} - - // blend_solid_hspan_min_subpix void blend_solid_hspan_min_subpix(int x, int y, unsigned len, const color_type& c, const uint8* covers, agg_buffer* buffer, const PatternHandler* pattern) { uint8* p = buffer->row_ptr(y) + (x << 2); + const int subpixelL = gSubpixelOrderingRGB ? 2 : 0; + const int subpixelM = 1; + const int subpixelR = gSubpixelOrderingRGB ? 0 : 2; do { rgb_color color = pattern->ColorAt(x, y); BLEND_MIN_SUBPIX(p, color.red, color.green, color.blue, - covers[2], covers[1], covers[0]); + covers[subpixelL], covers[subpixelM], covers[subpixelR]); covers += 3; p += 4; x++; diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeOverSUBPIX.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeOverSUBPIX.h index 91aa4edf51..d32861fce8 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeOverSUBPIX.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeOverSUBPIX.h @@ -11,6 +11,7 @@ #define DRAWING_MODE_OVER_SUBPIX_H #include "DrawingMode.h" +#include "GlobalSubpixelSettings.h" // BLEND_OVER_SUBPIX #define BLEND_OVER_SUBPIX(d, r, g, b, a1, a2, a3) \ @@ -19,58 +20,6 @@ } -// BLEND_OVER -#define BLEND_OVER(d, r, g, b, a) \ -{ \ - BLEND(d, r, g, b, a) \ -} - - -// ASSIGN_OVER -#define ASSIGN_OVER(d, r, g, b) \ -{ \ - d[0] = (b); \ - d[1] = (g); \ - d[2] = (r); \ - d[3] = 255; \ -} - - -// blend_hline_over_subpix -void -blend_hline_over_subpix(int x, int y, unsigned len, const color_type& c, - uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) -{ - if (cover == 255) { - rgb_color color = pattern->HighColor(); - uint32 v; - uint8* p8 = (uint8*)&v; - p8[0] = (uint8)color.blue; - p8[1] = (uint8)color.green; - p8[2] = (uint8)color.red; - p8[3] = 255; - uint32* p32 = (uint32*)(buffer->row_ptr(y)) + x; - do { - if (pattern->IsHighColor(x, y)) - *p32 = v; - p32++; - x++; - len -= 3; - } while (len); - } else { - uint8* p = buffer->row_ptr(y) + (x << 2); - rgb_color color = pattern->HighColor(); - do { - if (pattern->IsHighColor(x, y)) - BLEND_OVER(p, color.red, color.green, color.blue, cover); - x++; - p += 4; - len -= 3; - } while (len); - } -} - - // blend_solid_hspan_over_subpix void blend_solid_hspan_over_subpix(int x, int y, unsigned len, const color_type& c, @@ -78,10 +27,13 @@ blend_solid_hspan_over_subpix(int x, int y, unsigned len, const color_type& c, { uint8* p = buffer->row_ptr(y) + (x << 2); rgb_color color = pattern->HighColor(); + const int subpixelL = gSubpixelOrderingRGB ? 2 : 0; + const int subpixelM = 1; + const int subpixelR = gSubpixelOrderingRGB ? 0 : 2; do { if (pattern->IsHighColor(x, y)) { BLEND_OVER_SUBPIX(p, color.red, color.green, color.blue, - covers[2], covers[1], covers[0]); + covers[subpixelL], covers[subpixelM], covers[subpixelR]); } covers += 3; p += 4; diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeOverSolidSUBPIX.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeOverSolidSUBPIX.h index 0c45390438..9c05c7cd8f 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeOverSolidSUBPIX.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeOverSolidSUBPIX.h @@ -11,40 +11,7 @@ #define DRAWING_MODE_OVER_SOLID_SUBPIX_H #include "DrawingModeOverSUBPIX.h" - -// blend_hline_over_solid_subpix -void -blend_hline_over_solid_subpix(int x, int y, unsigned len, const color_type& c, - uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) -{ - if (pattern->IsSolidLow()) - return; - - if (cover == 255) { - uint32 v; - uint8* p8 = (uint8*)&v; - p8[0] = (uint8)c.b; - p8[1] = (uint8)c.g; - p8[2] = (uint8)c.r; - p8[3] = 255; - uint32* p32 = (uint32*)(buffer->row_ptr(y)) + x; - do { - *p32 = v; - p32++; - x++; - len -= 3; - } while (len); - } else { - uint8* p = buffer->row_ptr(y) + (x << 2); - do { - BLEND_OVER(p, c.r, c.g, c.b, cover); - x++; - p += 4; - len -= 3; - } while (len); - } -} - +#include "GlobalSubpixelSettings.h" // blend_solid_hspan_over_solid_subpix void @@ -56,8 +23,12 @@ blend_solid_hspan_over_solid_subpix(int x, int y, unsigned len, return; uint8* p = buffer->row_ptr(y) + (x << 2); + const int subpixelL = gSubpixelOrderingRGB ? 2 : 0; + const int subpixelM = 1; + const int subpixelR = gSubpixelOrderingRGB ? 0 : 2; do { - BLEND_OVER_SUBPIX(p, c.r, c.g, c.b, covers[2], covers[1], covers[0]); + BLEND_OVER_SUBPIX(p, c.r, c.g, c.b, + covers[subpixelL], covers[subpixelM], covers[subpixelR]); covers += 3; p += 4; x++; diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeSelectSUBPIX.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeSelectSUBPIX.h index e20ab7c925..f9eacb288d 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeSelectSUBPIX.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeSelectSUBPIX.h @@ -11,6 +11,7 @@ #define DRAWING_MODE_SELECT_SUBPIX_H #include "DrawingMode.h" +#include "GlobalSubpixelSettings.h" // BLEND_SELECT_SUBPIX #define BLEND_SELECT_SUBPIX(d, r, g, b, a1, a2, a3) \ @@ -19,55 +20,6 @@ } -// BLEND_SELECT -#define BLEND_SELECT(d, r, g, b, a) \ -{ \ - BLEND(d, r, g, b, a); \ -} - - -// ASSIGN_SELECT -#define ASSIGN_SELECT(d, r, g, b) \ -{ \ - d[0] = (b); \ - d[1] = (g); \ - d[2] = (r); \ - d[3] = 255; \ -} - - -// blend_hline_select_subpix -void -blend_hline_select_subpix(int x, int y, unsigned len, const color_type& c, - uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) -{ - uint8* p = buffer->row_ptr(y) + (x << 2); - rgb_color high = pattern->HighColor(); - rgb_color low = pattern->LowColor(); - rgb_color color; - if (cover == 255) { - do { - if (pattern->IsHighColor(x, y) - && compare(p, high, low, &color)) - ASSIGN_SELECT(p, color.red, color.green, color.blue); - x++; - p += 4; - len -= 3; - } while (len); - } else { - do { - if (pattern->IsHighColor(x, y) - && compare(p, high, low, &color)) { - BLEND_SELECT(p, color.red, color.green, color.blue, cover); - } - x++; - p += 4; - len -= 3; - } while (len); - } -} - - // blend_solid_hspan_select_subpix void blend_solid_hspan_select_subpix(int x, int y, unsigned len, const color_type& c, @@ -77,11 +29,14 @@ blend_solid_hspan_select_subpix(int x, int y, unsigned len, const color_type& c, rgb_color high = pattern->HighColor(); rgb_color low = pattern->LowColor(); rgb_color color; + const int subpixelL = gSubpixelOrderingRGB ? 2 : 0; + const int subpixelM = 1; + const int subpixelR = gSubpixelOrderingRGB ? 0 : 2; do { if (pattern->IsHighColor(x, y)) { if (compare(p, high, low, &color)){ BLEND_SELECT_SUBPIX(p, color.red, color.green, color.blue, - covers[2], covers[1], covers[0]); + covers[subpixelL], covers[subpixelM], covers[subpixelR]); } } covers += 3; diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeSubtractSUBPIX.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeSubtractSUBPIX.h index 3c2c96c594..d9bb81fdd9 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeSubtractSUBPIX.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeSubtractSUBPIX.h @@ -10,10 +10,8 @@ #ifndef DRAWING_MODE_SUBTRACT_SUBPIX_H #define DRAWING_MODE_SUBTRACT_SUBPIX_H -#include - #include "DrawingMode.h" -#include "PatternHandler.h" +#include "GlobalSubpixelSettings.h" // BLEND_SUBTRACT_SUBPIX #define BLEND_SUBTRACT_SUBPIX(d, r, g, b, a1, a2, a3) \ @@ -27,60 +25,6 @@ } -// BLEND_SUBTRACT -#define BLEND_SUBTRACT(d, r, g, b, a) \ -{ \ - pixel32 _p; \ - _p.data32 = *(uint32*)d; \ - uint8 rt = max_c(0, _p.data8[2] - (r)); \ - uint8 gt = max_c(0, _p.data8[1] - (g)); \ - uint8 bt = max_c(0, _p.data8[0] - (b)); \ - BLEND(d, rt, gt, bt, a); \ -} - - -// ASSIGN_SUBTRACT -#define ASSIGN_SUBTRACT(d, r, g, b) \ -{ \ - pixel32 _p; \ - _p.data32 = *(uint32*)d; \ - d[0] = max_c(0, _p.data8[0] - (b)); \ - d[1] = max_c(0, _p.data8[1] - (g)); \ - d[2] = max_c(0, _p.data8[2] - (r)); \ - d[3] = 255; \ -} - - -// blend_hline_subtract_subpix -void -blend_hline_subtract_subpix(int x, int y, unsigned len, const color_type& c, - uint8 cover, agg_buffer* buffer, const PatternHandler* pattern) -{ - uint8* p = buffer->row_ptr(y) + (x << 2); - if (cover == 255) { - do { - rgb_color color = pattern->ColorAt(x, y); - - ASSIGN_SUBTRACT(p, color.red, color.green, color.blue); - - p += 4; - x++; - len -= 3; - } while (len); - } else { - do { - rgb_color color = pattern->ColorAt(x, y); - - BLEND_SUBTRACT(p, color.red, color.green, color.blue, cover); - - x++; - p += 4; - len -= 3; - } while (len); - } -} - - // blend_solid_hspan_subtract_subpix void blend_solid_hspan_subtract_subpix(int x, int y, unsigned len, @@ -88,10 +32,13 @@ blend_solid_hspan_subtract_subpix(int x, int y, unsigned len, const PatternHandler* pattern) { uint8* p = buffer->row_ptr(y) + (x << 2); + const int subpixelL = gSubpixelOrderingRGB ? 2 : 0; + const int subpixelM = 1; + const int subpixelR = gSubpixelOrderingRGB ? 0 : 2; do { rgb_color color = pattern->ColorAt(x, y); BLEND_SUBTRACT_SUBPIX(p, color.red, color.green, color.blue, - covers[2], covers[1], covers[0]); + covers[subpixelL], covers[subpixelM], covers[subpixelR]); covers += 3; p += 4; x++; diff --git a/src/servers/app/drawing/Painter/drawing_modes/PixelFormat.cpp b/src/servers/app/drawing/Painter/drawing_modes/PixelFormat.cpp index d5499cda87..0e4508ffe3 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/PixelFormat.cpp +++ b/src/servers/app/drawing/Painter/drawing_modes/PixelFormat.cpp @@ -74,15 +74,6 @@ blend_hline_empty(int x, int y, unsigned len, printf("blend_hline_empty()\n"); } -// blend_hline_subpix_empty -void -blend_hline_empty_subpix(int x, int y, unsigned len, - const color_type& c, uint8 cover, - agg_buffer* buffer, const PatternHandler* pattern) -{ - printf("blend_hline_empty_subpix()\n"); -} - // blend_vline_empty void blend_vline_empty(int x, int y, unsigned len, @@ -151,7 +142,6 @@ PixelFormat::PixelFormat(agg::rendering_buffer& rb, fBlendPixel(blend_pixel_empty), fBlendHLine(blend_hline_empty), - fBlendHLineSubpix(blend_hline_empty_subpix), fBlendVLine(blend_vline_empty), fBlendSolidHSpan(blend_solid_hspan_empty), fBlendSolidHSpanSubpix(blend_solid_hspan_empty_subpix), @@ -181,12 +171,10 @@ PixelFormat::SetDrawingMode(drawing_mode mode, source_alpha alphaSrcMode, fBlendHLine = blend_hline_over_solid; fBlendSolidHSpan = blend_solid_hspan_over_solid; fBlendSolidVSpan = blend_solid_vspan_over_solid; - fBlendHLineSubpix = blend_hline_over_solid_subpix; fBlendSolidHSpanSubpix = blend_solid_hspan_over_solid_subpix; } else { fBlendPixel = blend_pixel_over; fBlendHLine = blend_hline_over; - fBlendHLineSubpix = blend_hline_over_subpix; fBlendSolidHSpanSubpix = blend_solid_hspan_over_subpix; fBlendSolidHSpan = blend_solid_hspan_over; fBlendSolidVSpan = blend_solid_vspan_over; @@ -196,7 +184,6 @@ PixelFormat::SetDrawingMode(drawing_mode mode, source_alpha alphaSrcMode, case B_OP_ERASE: fBlendPixel = blend_pixel_erase; fBlendHLine = blend_hline_erase; - fBlendHLineSubpix = blend_hline_erase_subpix; fBlendSolidHSpanSubpix = blend_solid_hspan_erase_subpix; fBlendSolidHSpan = blend_solid_hspan_erase; fBlendSolidVSpan = blend_solid_vspan_erase; @@ -205,7 +192,6 @@ PixelFormat::SetDrawingMode(drawing_mode mode, source_alpha alphaSrcMode, case B_OP_INVERT: fBlendPixel = blend_pixel_invert; fBlendHLine = blend_hline_invert; - fBlendHLineSubpix = blend_hline_invert_subpix; fBlendSolidHSpanSubpix = blend_solid_hspan_invert_subpix; fBlendSolidHSpan = blend_solid_hspan_invert; fBlendSolidVSpan = blend_solid_vspan_invert; @@ -214,7 +200,6 @@ PixelFormat::SetDrawingMode(drawing_mode mode, source_alpha alphaSrcMode, case B_OP_SELECT: fBlendPixel = blend_pixel_select; fBlendHLine = blend_hline_select; - fBlendHLineSubpix = blend_hline_select_subpix; fBlendSolidHSpanSubpix = blend_solid_hspan_select_subpix; fBlendSolidHSpan = blend_solid_hspan_select; fBlendSolidVSpan = blend_solid_vspan_select; @@ -227,7 +212,6 @@ PixelFormat::SetDrawingMode(drawing_mode mode, source_alpha alphaSrcMode, if (text) { fBlendPixel = blend_pixel_copy_text; fBlendHLine = blend_hline_copy_text; - fBlendHLineSubpix = blend_hline_copy_text_subpix; fBlendSolidHSpanSubpix = blend_solid_hspan_copy_text_subpix; fBlendSolidHSpan = blend_solid_hspan_copy_text; fBlendSolidVSpan = blend_solid_vspan_copy_text; @@ -239,7 +223,6 @@ PixelFormat::SetDrawingMode(drawing_mode mode, source_alpha alphaSrcMode, } else if (fPatternHandler->IsSolid()) { fBlendPixel = blend_pixel_copy_solid; fBlendHLine = blend_hline_copy_solid; - fBlendHLineSubpix = blend_hline_copy_solid_subpix; fBlendSolidHSpanSubpix = blend_solid_hspan_copy_solid_subpix; fBlendSolidHSpan = blend_solid_hspan_copy_solid; fBlendSolidVSpan = blend_solid_vspan_copy_solid; @@ -247,7 +230,6 @@ PixelFormat::SetDrawingMode(drawing_mode mode, source_alpha alphaSrcMode, } else { fBlendPixel = blend_pixel_copy; fBlendHLine = blend_hline_copy; - fBlendHLineSubpix = blend_hline_copy_subpix; fBlendSolidHSpanSubpix = blend_solid_hspan_copy_subpix; fBlendSolidHSpan = blend_solid_hspan_copy; fBlendSolidVSpan = blend_solid_vspan_copy; @@ -256,8 +238,7 @@ PixelFormat::SetDrawingMode(drawing_mode mode, source_alpha alphaSrcMode, break; case B_OP_ADD: fBlendPixel = blend_pixel_add; - fBlendHLine = blend_hline_add; - fBlendHLineSubpix = blend_hline_add_subpix; + fBlendHLine = blend_hline_add; fBlendSolidHSpanSubpix = blend_solid_hspan_add_subpix; fBlendSolidHSpan = blend_solid_hspan_add; fBlendSolidVSpan = blend_solid_vspan_add; @@ -266,7 +247,6 @@ PixelFormat::SetDrawingMode(drawing_mode mode, source_alpha alphaSrcMode, case B_OP_SUBTRACT: fBlendPixel = blend_pixel_subtract; fBlendHLine = blend_hline_subtract; - fBlendHLineSubpix = blend_hline_subtract_subpix; fBlendSolidHSpanSubpix = blend_solid_hspan_subtract_subpix; fBlendSolidHSpan = blend_solid_hspan_subtract; fBlendSolidVSpan = blend_solid_vspan_subtract; @@ -275,7 +255,6 @@ PixelFormat::SetDrawingMode(drawing_mode mode, source_alpha alphaSrcMode, case B_OP_BLEND: fBlendPixel = blend_pixel_blend; fBlendHLine = blend_hline_blend; - fBlendHLineSubpix = blend_hline_blend_subpix; fBlendSolidHSpanSubpix = blend_solid_hspan_blend_subpix; fBlendSolidHSpan = blend_solid_hspan_blend; fBlendSolidVSpan = blend_solid_vspan_blend; @@ -284,7 +263,6 @@ PixelFormat::SetDrawingMode(drawing_mode mode, source_alpha alphaSrcMode, case B_OP_MIN: fBlendPixel = blend_pixel_min; fBlendHLine = blend_hline_min; - fBlendHLineSubpix = blend_hline_min_subpix; fBlendSolidHSpanSubpix = blend_solid_hspan_min_subpix; fBlendSolidHSpan = blend_solid_hspan_min; fBlendSolidVSpan = blend_solid_vspan_min; @@ -293,7 +271,6 @@ PixelFormat::SetDrawingMode(drawing_mode mode, source_alpha alphaSrcMode, case B_OP_MAX: fBlendPixel = blend_pixel_max; fBlendHLine = blend_hline_max; - fBlendHLineSubpix = blend_hline_max_subpix; fBlendSolidHSpanSubpix = blend_solid_hspan_max_subpix; fBlendSolidHSpan = blend_solid_hspan_max; fBlendSolidVSpan = blend_solid_vspan_max; @@ -314,14 +291,12 @@ PixelFormat::SetDrawingMode(drawing_mode mode, source_alpha alphaSrcMode, if (fPatternHandler->IsSolid()) { fBlendPixel = blend_pixel_alpha_co_solid; fBlendHLine = blend_hline_alpha_co_solid; - fBlendHLineSubpix = blend_hline_alpha_co_solid_subpix; fBlendSolidHSpanSubpix = blend_solid_hspan_alpha_co_solid_subpix; fBlendSolidHSpan = blend_solid_hspan_alpha_co_solid; fBlendSolidVSpan = blend_solid_vspan_alpha_co_solid; } else { fBlendPixel = blend_pixel_alpha_co; fBlendHLine = blend_hline_alpha_co; - fBlendHLineSubpix = blend_hline_alpha_co_subpix; fBlendSolidHSpanSubpix = blend_solid_hspan_alpha_co_subpix; fBlendSolidHSpan = blend_solid_hspan_alpha_co; fBlendSolidVSpan = blend_solid_vspan_alpha_co; @@ -330,7 +305,6 @@ PixelFormat::SetDrawingMode(drawing_mode mode, source_alpha alphaSrcMode, } else if (alphaFncMode == B_ALPHA_COMPOSITE) { fBlendPixel = blend_pixel_alpha_cc; fBlendHLine = blend_hline_alpha_cc; - fBlendHLineSubpix = blend_hline_alpha_cc_subpix; fBlendSolidHSpanSubpix = blend_solid_hspan_alpha_cc_subpix; fBlendSolidHSpan = blend_solid_hspan_alpha_cc; fBlendSolidVSpan = blend_solid_vspan_alpha_cc; @@ -341,14 +315,12 @@ PixelFormat::SetDrawingMode(drawing_mode mode, source_alpha alphaSrcMode, if (fPatternHandler->IsSolid()) { fBlendPixel = blend_pixel_alpha_po_solid; fBlendHLine = blend_hline_alpha_po_solid; - fBlendHLineSubpix = blend_hline_alpha_po_solid_subpix; fBlendSolidHSpanSubpix = blend_solid_hspan_alpha_po_solid_subpix; fBlendSolidHSpan = blend_solid_hspan_alpha_po_solid; fBlendSolidVSpan = blend_solid_vspan_alpha_po_solid; } else { fBlendPixel = blend_pixel_alpha_po; fBlendHLine = blend_hline_alpha_po; - fBlendHLineSubpix = blend_hline_alpha_po_subpix; fBlendSolidHSpanSubpix = blend_solid_hspan_alpha_po_subpix; fBlendSolidHSpan = blend_solid_hspan_alpha_po; fBlendSolidVSpan = blend_solid_vspan_alpha_po; @@ -357,7 +329,6 @@ PixelFormat::SetDrawingMode(drawing_mode mode, source_alpha alphaSrcMode, } else if (alphaFncMode == B_ALPHA_COMPOSITE) { fBlendPixel = blend_pixel_alpha_pc; fBlendHLine = blend_hline_alpha_pc; - fBlendHLineSubpix = blend_hline_alpha_pc_subpix; fBlendSolidHSpanSubpix = blend_solid_hspan_alpha_pc_subpix; fBlendSolidHSpan = blend_solid_hspan_alpha_pc; fBlendSolidVSpan = blend_solid_vspan_alpha_pc; diff --git a/src/servers/app/drawing/Painter/drawing_modes/PixelFormat.h b/src/servers/app/drawing/Painter/drawing_modes/PixelFormat.h index 609eea36f7..d0c8bc7689 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/PixelFormat.h +++ b/src/servers/app/drawing/Painter/drawing_modes/PixelFormat.h @@ -105,11 +105,6 @@ class PixelFormat { const color_type& c, uint8 cover); - inline void blend_hline_subpix(int x, int y, - unsigned len, - const color_type& c, - uint8 cover); - inline void blend_vline(int x, int y, unsigned len, const color_type& c, @@ -149,7 +144,6 @@ class PixelFormat { blend_pixel_f fBlendPixel; blend_line fBlendHLine; - blend_line fBlendHLineSubpix; blend_line fBlendVLine; blend_solid_span fBlendSolidHSpan; blend_solid_span fBlendSolidHSpanSubpix; @@ -211,14 +205,6 @@ PixelFormat::blend_hline(int x, int y, unsigned len, fBlendHLine(x, y, len, c, cover, fBuffer, fPatternHandler); } -// blend_hline_subpix -inline void -PixelFormat::blend_hline_subpix(int x, int y, unsigned len, - const color_type& c, uint8 cover) -{ - fBlendHLineSubpix(x, y, len, c, cover, fBuffer, fPatternHandler); -} - // blend_vline inline void PixelFormat::blend_vline(int x, int y, unsigned len, diff --git a/src/tests/servers/app/Jamfile b/src/tests/servers/app/Jamfile index 262fc2a46d..6a764de18b 100644 --- a/src/tests/servers/app/Jamfile +++ b/src/tests/servers/app/Jamfile @@ -70,6 +70,7 @@ SharedLibrary libhaikuappserver.so : FontFamily.cpp FontManager.cpp FontStyle.cpp + GlobalSubpixelSettings.cpp HashTable.cpp IntPoint.cpp IntRect.cpp