[haiku-gsoc] Subpixel Milestone

  • From: Stephan Assmus <superstippi@xxxxxx>
  • To: haiku-gsoc@xxxxxxxxxxxxx
  • Date: Sun, 06 Jul 2008 02:46:35 +0200

Hi all,

attached is the first milestone of Andrej's work. Subpixel anti-aliased 
text rendering is working for untransformed text and can be turned on/off 
via the Fonts preflet.

I am happy with this patch and would like to commit it, but I will wait a 
bit for your input. Feel free to review and comment!

Best regards,
-Stephan
Index: headers/private/app/ServerProtocol.h
===================================================================
--- headers/private/app/ServerProtocol.h        (revision 26259)
+++ headers/private/app/ServerProtocol.h        (working copy)
@@ -6,6 +6,7 @@
  *             DarkWyrm <bpmagic@xxxxxxxxxxxxxxx>
  *             Jérôme Duval, jerome.duval@xxxxxxx
  *             Axel Dörfler, axeld@xxxxxxxxxxxxxxxx
+ *             Andrej Spielmann, <andrej.spielmann@xxxxxxxxxxxx>
  */
 #ifndef APP_SERVER_PROTOCOL_H
 #define APP_SERVER_PROTOCOL_H
@@ -187,6 +188,11 @@
        AS_GET_DECORATOR_SETTINGS,
        AS_GET_SHOW_ALL_DRAGGERS,
        AS_SET_SHOW_ALL_DRAGGERS,
+       
+       AS_SET_FONT_SUBPIXEL_ANTIALIASING,
+       AS_GET_FONT_SUBPIXEL_ANTIALIASING,
+       AS_SET_HINTING,
+       AS_GET_HINTING,
 
        // Graphics calls
        AS_SET_HIGH_COLOR,
Index: src/preferences/fonts/MainWindow.h
===================================================================
--- src/preferences/fonts/MainWindow.h  (revision 26259)
+++ src/preferences/fonts/MainWindow.h  (working copy)
@@ -12,6 +12,7 @@
 
 
 #include "FontsSettings.h"
+#include "AdvancedSettingsView.h"
 
 #include <Window.h>
 
@@ -31,12 +32,13 @@
        private:
                void                    _Center();
 
-               BMessageRunner* fRunner;
-               FontView*               fFontsView;
-               BButton*                fDefaultsButton;
-               BButton*                fRevertButton;
+               BMessageRunner*                 fRunner;
+               FontView*                               fFontsView;
+               BButton*                                fDefaultsButton;
+               BButton*                                fRevertButton;
 
-               FontsSettings   fSettings;
+               FontsSettings                   fSettings;
+               AdvancedSettingsView*   fAdvancedSettings;
 };
 
 static const int32 kMsgUpdate = 'updt';
Index: src/preferences/fonts/AdvancedSettingsView.cpp
===================================================================
--- src/preferences/fonts/AdvancedSettingsView.cpp      (revision 0)
+++ src/preferences/fonts/AdvancedSettingsView.cpp      (revision 0)
@@ -0,0 +1,279 @@
+/*
+ * Copyright 2008, Haiku. All rights reserved.
+ * Distributed under the terms of the MIT License.
+ *
+ * Authors:
+ *             Andrej Spielmann, <andrej.spielmann@xxxxxxxxxxxx>
+ */
+
+
+#include "AdvancedSettingsView.h"
+#include "MainWindow.h"
+
+#include <Box.h>
+#include <MenuField.h>
+#include <MenuItem.h>
+#include <PopUpMenu.h>
+#include <String.h>
+
+#include <stdio.h>
+
+
+#define INSTANT_UPDATE
+       // if defined, the changes will take place immediately and not only on 
exit
+#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 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);
+
+
+//     #pragma mark -
+
+
+AdvancedSettingsView::AdvancedSettingsView(BRect _rect, const char* name)
+       : BView(_rect, name, B_FOLLOW_LEFT_RIGHT, B_WILL_DRAW)
+{
+       if (_get_font_subpixel_antialiasing_(&fCurrentSubpixelAntialiasing) != 
B_OK)
+               fCurrentSubpixelAntialiasing = false;
+       fSavedSubpixelAntialiasing = fCurrentSubpixelAntialiasing;
+       
+       if (_get_hinting_(&fCurrentHinting) != B_OK)
+               fCurrentHinting = true;
+       fSavedHinting = fCurrentHinting;
+
+       fDivider = StringWidth("Character hinting:") + 5;
+       
+       fAntialiasingMenu = new BPopUpMenu("Antialiasing menu");
+       fHintingMenu = new BPopUpMenu("Hinting menu");
+
+       // antialiasing menu
+       BRect rect(Bounds());
+       fAntialiasingMenuField = new BMenuField(rect, "antialiasing",
+               "Antialiasing type:", fAntialiasingMenu, false);
+       fAntialiasingMenuField->SetDivider(fDivider);
+       fAntialiasingMenuField->SetAlignment(B_ALIGN_RIGHT);
+       fAntialiasingMenuField->ResizeToPreferred();
+       AddChild(fAntialiasingMenuField);
+       _BuildAntialiasingMenu();
+       
+       // hinting menu
+       float shift = fAntialiasingMenuField->Bounds().Height()+5;
+       rect.top += shift;
+       rect.bottom += shift;
+       fHintingMenuField = new BMenuField(rect, "hinting",
+               "Character hinting:", fHintingMenu, false);
+       fHintingMenuField->SetDivider(fDivider);
+       fHintingMenuField->SetAlignment(B_ALIGN_RIGHT);
+       fHintingMenuField->ResizeToPreferred();
+       AddChild(fHintingMenuField);
+       _BuildHintingMenu();
+       
+#ifdef DISABLE_HINTING_CONTROL
+       fHintingMenuField->SetEnabled(false);
+#endif
+       
+       _SetCurrentAntialiasing();
+       _SetCurrentHinting();
+}
+
+
+AdvancedSettingsView::~AdvancedSettingsView()
+{
+#ifndef INSTANT_UPDATE
+       _set_font_subpixel_antialiasing_(fCurrentSubpixelAntialiasing);
+       _set_hinting(fCurrentHinting);
+#endif
+}
+
+
+void
+AdvancedSettingsView::GetPreferredSize(float *_width, float *_height)
+{
+       // don't change the width if it is large enough
+       if (_width) {
+               *_width = (StringWidth(kSubpixelLabel) > 
StringWidth(kGrayscaleLabel) ?
+                       StringWidth(kSubpixelLabel) : 
StringWidth(kGrayscaleLabel))
+                       + fDivider + 30;
+               if (*_width < Bounds().Width())
+                       *_width = Bounds().Width();
+       }
+
+       *_height = fHintingMenuField->Frame().bottom;
+}
+
+
+void
+AdvancedSettingsView::SetDivider(float divider)
+{
+       fAntialiasingMenuField->SetDivider(divider);
+       fHintingMenuField->SetDivider(divider);
+       fDivider = divider;
+}
+
+
+void
+AdvancedSettingsView::RelayoutIfNeeded()
+{
+       float width, height;
+       GetPreferredSize(&width, &height);
+
+       if (width > Bounds().Width() || height > Bounds().Height()) {
+               ResizeTo(width, height);
+       }
+}
+
+
+void
+AdvancedSettingsView::AttachedToWindow()
+{
+       if (Parent() != NULL)
+               SetViewColor(Parent()->ViewColor());
+       else
+               SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
+       fAntialiasingMenu->SetTargetForItems(this);
+       fHintingMenu->SetTargetForItems(this);
+}
+
+
+void
+AdvancedSettingsView::MessageReceived(BMessage *msg)
+{
+       switch (msg->what) {
+               case kMsgSetAntialiasing:
+               {
+                       bool subpixelAntialiasing;
+                       if (msg->FindBool("antialiasing", 
&subpixelAntialiasing) != B_OK 
+                               || subpixelAntialiasing == 
fCurrentSubpixelAntialiasing)
+                               break;
+                       fCurrentSubpixelAntialiasing = subpixelAntialiasing;
+#ifdef INSTANT_UPDATE
+                       
_set_font_subpixel_antialiasing_(fCurrentSubpixelAntialiasing);
+#endif
+                       Window()->PostMessage(kMsgUpdate);
+                       break;
+               }
+               case kMsgSetHinting:
+               {
+                       bool hinting;
+                       if (msg->FindBool("hinting", &hinting) != B_OK 
+                               || hinting == fCurrentHinting)
+                               break;
+                       fCurrentHinting = hinting;
+#ifdef INSTANT_UPDATE
+                       _set_hinting_(fCurrentHinting);
+#endif
+                       Window()->PostMessage(kMsgUpdate);
+                       break;
+               }
+               default:
+                       BView::MessageReceived(msg);
+       }
+}
+
+
+void
+AdvancedSettingsView::_BuildAntialiasingMenu()
+{
+       BMessage* message = new BMessage(kMsgSetAntialiasing);
+       message->AddBool("antialiasing", false);
+
+       BMenuItem* item = new BMenuItem(kGrayscaleLabel, message);
+
+       fAntialiasingMenu->AddItem(item);
+       
+       BMessage* message2 = new BMessage(kMsgSetAntialiasing);
+       message2->AddBool("antialiasing", true);
+
+       BMenuItem* item2 = new BMenuItem(kSubpixelLabel, message2);
+
+       fAntialiasingMenu->AddItem(item2);
+}
+
+
+void
+AdvancedSettingsView::_BuildHintingMenu()
+{
+       BMessage* message = new BMessage(kMsgSetHinting);
+       message->AddBool("hinting", false);
+
+       BMenuItem* item = new BMenuItem(kNoHintingLabel, message);
+
+       fHintingMenu->AddItem(item);
+       
+       BMessage* message2 = new BMessage(kMsgSetHinting);
+       message2->AddBool("hinting", true);
+
+       BMenuItem* item2 = new BMenuItem(kFullHintingLabel, message2);
+
+       fHintingMenu->AddItem(item2);
+}
+
+
+void
+AdvancedSettingsView::_SetCurrentAntialiasing()
+{
+       BMenuItem *item = fAntialiasingMenu->FindItem(
+               fCurrentSubpixelAntialiasing ? kSubpixelLabel : 
kGrayscaleLabel);
+       if (item != NULL)
+               item->SetMarked(true);
+}
+
+
+void
+AdvancedSettingsView::_SetCurrentHinting()
+{
+       BMenuItem *item = fHintingMenu->FindItem(
+               fCurrentHinting ? kFullHintingLabel : kNoHintingLabel);
+       if (item != NULL)
+               item->SetMarked(true);
+}
+
+
+void
+AdvancedSettingsView::SetDefaults()
+{      
+}
+
+
+bool
+AdvancedSettingsView::IsDefaultable()
+{
+       return false;
+}
+
+
+bool
+AdvancedSettingsView::IsRevertable()
+{
+       return (fCurrentSubpixelAntialiasing != fSavedSubpixelAntialiasing) 
+               || (fCurrentHinting != fSavedHinting);
+}
+
+
+void
+AdvancedSettingsView::Revert()
+{
+       if (!IsRevertable())
+               return;
+
+       fCurrentSubpixelAntialiasing = fSavedSubpixelAntialiasing;
+       fCurrentHinting = fSavedHinting;
+#ifdef INSTANT_UPDATE
+       _set_font_subpixel_antialiasing_(fCurrentSubpixelAntialiasing);
+       _set_hinting_(fCurrentHinting);
+#endif
+       _SetCurrentAntialiasing();
+       _SetCurrentHinting();
+}
Index: src/preferences/fonts/FontView.h
===================================================================
--- src/preferences/fonts/FontView.h    (revision 26259)
+++ src/preferences/fonts/FontView.h    (working copy)
@@ -12,6 +12,7 @@
 
 
 #include "FontSelectionView.h"
+#include "AdvancedSettingsView.h"
 
 
 class FontView : public BView {
@@ -29,9 +30,9 @@
                bool    IsRevertable();
 
        private:
-               FontSelectionView       *fPlainView;
-               FontSelectionView       *fBoldView;
-               FontSelectionView       *fFixedView;
+               FontSelectionView               *fPlainView;
+               FontSelectionView               *fBoldView;
+               FontSelectionView               *fFixedView;
 };
        
 #endif /* FONT_VIEW_H */
Index: src/preferences/fonts/Jamfile
===================================================================
--- src/preferences/fonts/Jamfile       (revision 26259)
+++ src/preferences/fonts/Jamfile       (working copy)
@@ -5,6 +5,7 @@
 
 Preference Fonts :
        FontSelectionView.cpp
+       AdvancedSettingsView.cpp
        FontsSettings.cpp
        FontView.cpp
        main.cpp
Index: src/preferences/fonts/AdvancedSettingsView.h
===================================================================
--- src/preferences/fonts/AdvancedSettingsView.h        (revision 0)
+++ src/preferences/fonts/AdvancedSettingsView.h        (revision 0)
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2001-2005, Haiku.
+ * Distributed under the terms of the MIT License.
+ *
+ * Authors:
+ *             Andrej Spielmann, <andrej.spielmann@xxxxxxxxxxxx>
+ */
+#ifndef ADVANCED_SETTINGS_VIEW_H
+#define ADVANCED_SETTINGS_VIEW_H
+
+
+#include <View.h>
+
+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 */
Index: src/preferences/fonts/MainWindow.cpp
===================================================================
--- src/preferences/fonts/MainWindow.cpp        (revision 26259)
+++ src/preferences/fonts/MainWindow.cpp        (working copy)
@@ -6,6 +6,7 @@
  *             Mark Hogben
  *             DarkWyrm <bpmagic@xxxxxxxxxxxxxxx>
  *             Axel Dörfler, axeld@xxxxxxxxxxxxxxxx
+ *             Andrej Spielmann, <andrej.spielmann@xxxxxxxxxxxx>
  */
 
 
@@ -25,7 +26,7 @@
 
 
 MainWindow::MainWindow()
-       : BWindow(BRect(100, 100, 445, 340), "Fonts", B_TITLED_WINDOW,
+       : BWindow(BRect(100, 100, 445, 410), "Fonts", B_TITLED_WINDOW,
                B_NOT_RESIZABLE | B_ASYNCHRONOUS_CONTROLS | B_NOT_ZOOMABLE)
 {
        BRect rect = Bounds();
@@ -60,6 +61,8 @@
 
        rect = tabView->ContainerView()->Bounds().InsetByCopy(5, 8);
        fFontsView = new FontView(rect);
+       
+       fAdvancedSettings = new AdvancedSettingsView(rect, "Advanced");
 
        tabView->AddTab(fFontsView);
 
@@ -83,7 +86,8 @@
                tabView->ContainerView()->ResizeBy(0, heightDiff);
        }
 
-       ResizeTo(tabView->Bounds().Width() + 10, tabView->Frame().bottom + 20 + 
buttonHeight);
+       ResizeTo(tabView->Bounds().Width() + 10, tabView->Frame().bottom + 20
+               + buttonHeight);
        view->AddChild(tabView);
        fFontsView->ResizeToPreferred();
 
@@ -98,6 +102,23 @@
                if (!screen.Frame().InsetByCopy(10, 10).Intersects(Frame()))
                        _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
@@ -127,19 +148,25 @@
 {
        switch (message->what) {
                case kMsgUpdate:
-                       
fDefaultsButton->SetEnabled(fFontsView->IsDefaultable());
-                       fRevertButton->SetEnabled(fFontsView->IsRevertable());
+                       fDefaultsButton->SetEnabled(fFontsView->IsDefaultable()
+                                                               || 
fAdvancedSettings->IsDefaultable());
+                       fRevertButton->SetEnabled(fFontsView->IsRevertable()
+                                                               || 
fAdvancedSettings->IsRevertable());
                        break;
 
                case kMsgSetDefaults:
                        fFontsView->SetDefaults();
+                       fAdvancedSettings->SetDefaults();
                        fDefaultsButton->SetEnabled(false);
-                       fRevertButton->SetEnabled(fFontsView->IsRevertable());
+                       fRevertButton->SetEnabled(fFontsView->IsRevertable()
+                                                               || 
fAdvancedSettings->IsRevertable());
                        break;
 
                case kMsgRevert:
                        fFontsView->Revert();
-                       
fDefaultsButton->SetEnabled(fFontsView->IsDefaultable());
+                       fAdvancedSettings->Revert();
+                       fDefaultsButton->SetEnabled(fFontsView->IsDefaultable()
+                                                               || 
fAdvancedSettings->IsDefaultable());
                        fRevertButton->SetEnabled(false);
                        break;
 
Index: headers/libs/agg/agg_renderer_base.h
===================================================================
--- headers/libs/agg/agg_renderer_base.h        (revision 26259)
+++ headers/libs/agg/agg_renderer_base.h        (working copy)
@@ -205,7 +205,23 @@
 
             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, 
                          const color_type& c, cover_type cover)
@@ -280,7 +296,30 @@
             }
             m_ren->blend_solid_hspan(x, y, len, c, covers);
         }
+               
+               
//--------------------------------------------------------------------
+        void blend_solid_hspan_subpix(int x, int y, int len, 
+                                      const color_type& c, 
+                                      const cover_type* covers)
+        {
+            if(y > ymax()) return;
+            if(y < ymin()) return;
 
+            if(x < xmin())
+            {
+                len -= 3 * (xmin() - x);
+                if(len <= 0) return;
+                covers += 3*(xmin() - x);
+                x = xmin();
+            }
+            if(x + len / 3 > xmax())
+            {
+                len = 3 * (xmax() - x + 1);
+                if(len <= 0) return;
+            }
+            m_ren->blend_solid_hspan_subpix(x, y, len, c, covers);
+        }
+
         //--------------------------------------------------------------------
         void blend_solid_vspan(int x, int y, int len, 
                                const color_type& c, 
Index: src/servers/app/DesktopSettings.h
===================================================================
--- src/servers/app/DesktopSettings.h   (revision 26239)
+++ src/servers/app/DesktopSettings.h   (working copy)
@@ -4,6 +4,7 @@
  *
  * Authors:
  *             Axel Dörfler, axeld@xxxxxxxxxxxxxxxx
+ *             Andrej Spielmann, <andrej.spielmann@xxxxxxxxxxxx>
  */
 #ifndef DESKTOP_SETTINGS_H
 #define DESKTOP_SETTINGS_H
@@ -51,6 +52,9 @@
                const BMessage* WorkspacesMessage(int32 index) const;
 
                rgb_color               UIColor(color_which which) const;
+               
+               bool                    FontSubpixelAntialiasing() const;
+               bool                    Hinting() const;
 
        protected:
                DesktopSettingsPrivate* fSettings;
@@ -73,6 +77,9 @@
                void                    SetShowAllDraggers(bool show);
 
                void                    SetUIColor(color_which which, const 
rgb_color color);
+               
+               void                    SetFontSubpixelAntialiasing(bool 
subpix);
+               void                    SetHinting(bool hinting);
 
        private:
                Desktop*                fDesktop;
Index: src/servers/app/FontCacheEntry.cpp
===================================================================
--- src/servers/app/FontCacheEntry.cpp  (revision 26239)
+++ src/servers/app/FontCacheEntry.cpp  (working copy)
@@ -5,6 +5,7 @@
  * Authors:
  *             Maxim Shemanarev <mcseemagg@xxxxxxxxx>
  *             Stephan Aßmus <superstippi@xxxxxx>
+ *             Andrej Spielmann, <andrej.spielmann@xxxxxxxxxxxx>
  */
 
 //----------------------------------------------------------------------------
@@ -35,7 +36,13 @@
 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 };
@@ -120,7 +127,7 @@
 
        // TODO: encoding from font
        FT_Encoding charMap = FT_ENCODING_NONE;
-       bool hinting = true; // TODO: font.Hinting();
+       bool hinting = sDefaultHinting; // TODO: font.Hinting();
 
        if (!fEngine.Init(font.Path(), 0, font.Size(), charMap,
                        renderingType, hinting)) {
@@ -187,6 +194,10 @@
                case glyph_data_gray8:
                        gray8Adapter.init(glyph->data, glyph->data_size, x, y);
                        break;
+                       
+               case glyph_data_subpix:
+                       gray8Adapter.init(glyph->data, glyph->data_size, x, y);
+                       break;
 
                case glyph_data_outline:
                        pathAdapter.init(glyph->data, glyph->data_size, x, y, 
scale);
@@ -213,7 +224,7 @@
 
        // TODO: read more of these from the font
        FT_Encoding charMap = FT_ENCODING_NONE;
-       bool hinting = true; // TODO: font.Hinting();
+       bool hinting = sDefaultHinting; // TODO: font.Hinting();
 
        sprintf(signature, "%ld,%u,%d,%d,%.1f,%d",
                font.GetFamilyAndStyle(), charMap,
@@ -235,15 +246,29 @@
        fUseCounter++;
 }
 
+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 = glyph_ren_native_gray8;
+       glyph_rendering renderingType = sDefaultRenderType;
        if (font.Rotation() != 0.0 || font.Shear() != 90.0
                || font.FalseBoldWidth() != 0.0
                || font.Flags() & B_DISABLE_ANTIALIASING
-               || font.Size() > 30) {
+               || font.Size() > 30
+               || !sDefaultHinting) {
                renderingType = glyph_ren_outline;
        }
        return renderingType;
Index: src/servers/app/FontEngine.cpp
===================================================================
--- src/servers/app/FontEngine.cpp      (revision 26239)
+++ src/servers/app/FontEngine.cpp      (working copy)
@@ -6,6 +6,7 @@
  *             Maxim Shemanarev <mcseemagg@xxxxxxxxx>
  *             Stephan Aßmus <superstippi@xxxxxx>
  *             Anthony Lee <don.anthony.lee@xxxxxxxxx>
+ *             Andrej Spielmann, <andrej.spielmann@xxxxxxxxxxxx>
  */
 
 //----------------------------------------------------------------------------
@@ -26,12 +27,18 @@
 
 #include "FontEngine.h"
 
+#include FT_GLYPH_H
+#include FT_OUTLINE_H
+#include FT_LCD_FILTER_H
+
 #include <stdio.h>
 
 #include <agg_bitset_iterator.h>
 #include <agg_renderer_scanline.h>
 
 
+
+
 static const bool kFlipY = true;
 
 
@@ -359,7 +366,145 @@
        }
 }
 
+// decompose_ft_bitmap_subpix
+template<class Scanline, class ScanlineStorage>
+void
+decompose_ft_bitmap_subpix(const FT_Bitmap& bitmap, int x, int y,
+       bool flip_y, Scanline& sl, ScanlineStorage& storage)
+{
+       //Filtering weights
+       const uint8 filter[5] = { 0x10, 0x40, 0x70, 0x40, 0x10 };
 
+       int i, j;
+       const uint8* buf = (const uint8*)bitmap.buffer;
+       int pitch = bitmap.pitch;
+       sl.reset(x-1, x + bitmap.width/3 + 1);
+       storage.prepare();
+       if (flip_y) {
+               buf += bitmap.pitch * (bitmap.rows - 1);
+               y += bitmap.rows;
+               pitch = -pitch;
+       }
+       for (i = 0; i < bitmap.rows; i++) {
+               sl.reset_spans();
+
+               if (bitmap.pixel_mode == FT_PIXEL_MODE_MONO) {
+                       // font has built-in mono bitmap
+                       agg::bitset_iterator bits(buf, 0);
+                       int j;
+                       for (j = 0; j < bitmap.width; j++) {
+                               if (bits.bit())
+                                       sl.add_cell(x + j,
+                                               agg::cover_full, 
agg::cover_full, agg::cover_full);
+                               ++bits;
+                       }
+               } else {
+                       const uint8* p = buf;
+                       uint32 coverRed;
+                       uint32 coverGreen;
+                       uint32 coverBlue;
+                       int w = bitmap.width/3;
+                       if (w && !((p[0] == p[1] && p[1] == p[2])
+                                               && (w == 1 || (p[3] == p[4] && 
p[4] == p[5])))){
+                               coverRed = 0;
+                               coverGreen = (p[0] * filter[0]) >> 8;
+                               coverBlue = (p[0] * filter[1] + p[1] * 
filter[0]) >> 8;
+                               coverGreen = coverGreen | ( -(coverGreen >> 8));
+                               coverBlue = coverBlue | ( -(coverBlue >> 8));
+                               if (coverRed || coverGreen || coverBlue){
+                                       sl.add_cell(x - 1, coverRed, 
coverGreen, coverBlue);
+                               }
+                       }
+                       for (j = 0; j < w; j++) {
+                               if ((p[0] == p[1] && p[1] == p[2]) 
+                                       && (j == 0 || (p[-3] == p[-2] && p[-2] 
== p[-1]))
+                                       && (j == w-1 || (p[3] == p[4] && p[4] 
== p[5]))){
+                                       coverRed = p[0];
+                                       coverGreen = p[0];
+                                       coverBlue = p[0];
+                               }
+                               else if ((p[0] == p[1] && p[1] == p[2]) 
+                                               && (j < w-1 && p[3] == p[4] && 
p[4] == p[5])
+                                               && (j == w-2 || (p[6] == p[7] 
&& p[7] == p[8]))){
+                                               coverRed = (((j > 0) ? (p[-2] * 
filter[4]
+                                                                               
                + p[-1] * filter[3]) : 0) 
+                                                               + p[0] * 
filter[2] + p[1] * filter[1]
+                                                               + p[2] * 
filter[0]) 
+                                                               >> 8;
+                                               coverGreen = (((j > 0) ? (p[-1] 
* filter[4]) : 0) 
+                                                               + p[0] * 
filter[3] + p[1] * filter[2]
+                                                               + p[2] * 
filter[1]) 
+                                                               >> 8;
+                                               coverBlue = (p[0] * filter[4]
+                                                               + p[1] * 
filter[3] + p[2] * filter[2]) >> 8;
+                                               coverRed = coverRed | ( 
-(coverRed >> 8));
+                                               coverGreen = coverGreen | ( 
-(coverGreen >> 8));
+                                               coverBlue = coverBlue | ( 
-(coverBlue >> 8));
+                               }
+                               else if ((p[0] == p[1] && p[1] == p[2])
+                                               && (j > 0 && p[-3] == p[-2] && 
p[-2] == p[-1])
+                                               && (j == 1 || (p[-6] == p[-5] 
&& p[-5] == p[-4]))){
+                                               coverRed = (p[0] * filter[2] + 
p[1] * filter[1]
+                                                               + p[2] * 
filter[0]) >> 8;
+                                               coverGreen = (p[0] * filter[3] 
+ p[1] * filter[2]
+                                                                       + p[2] 
* filter[1] 
+                                                                       + ((j < 
w-1) ? (p[3] * filter[0]) : 0)) 
+                                                                       >> 8;
+                                               coverBlue = (p[0] * filter[4] + 
p[1] * filter[3]
+                                                                       + p[2] 
* filter[2] 
+                                                                       + ((j < 
w-1) ? (p[3] * filter[1]
+                                                                               
                        + p[4] * filter[0]) : 0)) 
+                                                                       >> 8;
+                                               coverRed = coverRed | ( 
-(coverRed >> 8));
+                                               coverGreen = coverGreen | ( 
-(coverGreen >> 8));
+                                               coverBlue = coverBlue | ( 
-(coverBlue >> 8));                                   
+                               }
+                               else {
+                                       coverRed = (((j > 0)?(p[-2] * filter[4]
+                                                       + p[-1] * filter[3]):0) 
+                                                       + p[0] * filter[2] + 
p[1] * filter[1]
+                                                       + p[2] * filter[0]) 
+                                                       >> 8;
+                                       coverGreen = (((j > 0) ? (p[-1] * 
filter[4]) : 0) 
+                                                               + p[0] * 
filter[3] + p[1] * filter[2]
+                                                               + p[2] * 
filter[1] 
+                                                               + ((j < w-1) ? 
(p[3] * filter[0]) : 0)) 
+                                                               >> 8;
+                                       coverBlue = (p[0] * filter[4] + p[1] * 
filter[3]
+                                                               + p[2] * 
filter[2] 
+                                                               + ((j < w-1) ? 
(p[3] * filter[1]
+                                                                               
+ p[4] * filter[0]) : 0)) 
+                                                               >> 8;
+                                       coverRed = coverRed | ( -(coverRed >> 
8));
+                                       coverGreen = coverGreen | ( 
-(coverGreen >> 8));
+                                       coverBlue = coverBlue | ( -(coverBlue 
>> 8));
+                               }
+                               if (coverRed || coverGreen || coverBlue) {
+                                               sl.add_cell(x + j, coverRed, 
coverGreen, coverBlue);
+                               }
+                               p+=3;
+                       }
+                       if (w && !((p[-3] == p[-2] && p[-2] == p[-1])
+                                               && (w == 1 || (p[-6] == p[-5] 
&& p[-5] == p[-4])))){
+                               coverRed = (p[-2] * filter[4] + p[-1] * 
filter[3]) >> 8;
+                               coverGreen = (p[-1] * filter[4]) >> 8;
+                               coverBlue = 0;
+                               coverRed = coverRed | ( -(coverRed >> 8));
+                               coverGreen = coverGreen | ( -(coverGreen >> 8));
+                               if (coverRed || coverGreen || coverBlue){
+                                       sl.add_cell(x + w, coverRed, 
coverGreen, coverBlue);
+                               }
+                       }                       
+               }
+
+               buf += pitch;
+               if (sl.num_spans()) {
+                       sl.finalize(y - i - 1);
+                       storage.render(sl);
+               }
+       }
+}
+
 // #pragma mark -
 
 
@@ -386,8 +531,10 @@
        , fCurves(fPath)
        , fScanlineAA()
        , fScanlineBin()
+       , fScanlineSubpix()
        , fScanlineStorageAA()
        , fScanlineStorageBin()
+       , fScanlineStorageSubpix()
 {
        fCurves.approximation_scale(4.0);
 
@@ -421,7 +568,7 @@
 {
        fGlyphIndex = FT_Get_Char_Index(fFace, glyphCode);
        fLastError = FT_Load_Glyph(fFace, fGlyphIndex,
-               fHinting ? FT_LOAD_DEFAULT : FT_LOAD_NO_HINTING);
+               (fHinting ? (FT_LOAD_DEFAULT | FT_LOAD_TARGET_LCD) : 
FT_LOAD_NO_HINTING));
 //             fHinting ? FT_LOAD_FORCE_AUTOHINT : FT_LOAD_NO_HINTING);
 
        if (fLastError != 0)
@@ -469,7 +616,25 @@
                        }
                        break;
        
-       
+                                       
+               case glyph_ren_subpix:
+                       fLastError = FT_Render_Glyph(fFace->glyph, 
FT_RENDER_MODE_LCD);
+                       if (fLastError == 0) {
+                               
decompose_ft_bitmap_subpix(fFace->glyph->bitmap, 
+                                       fFace->glyph->bitmap_left, kFlipY ?
+                                       -fFace->glyph->bitmap_top : 
fFace->glyph->bitmap_top,
+                                       kFlipY, fScanlineSubpix, 
fScanlineStorageSubpix);
+                               fBounds.x1 = fScanlineStorageSubpix.min_x();
+                               fBounds.y1 = fScanlineStorageSubpix.min_y();
+                               fBounds.x2 = fScanlineStorageSubpix.max_x();
+                               fBounds.y2 = fScanlineStorageSubpix.max_y();
+                               fDataSize = fScanlineStorageSubpix.byte_size(); 
+                               fDataType = glyph_data_subpix;
+                               return true;
+                       }
+                       break;
+                       
+               
                case glyph_ren_outline:
                        fPath.remove_all();
                        if (decompose_ft_outline(fFace->glyph->outline, kFlipY, 
fPath)) {
@@ -502,6 +667,10 @@
                        case glyph_data_gray8:
                                fScanlineStorageAA.serialize(data); 
                                break;
+                               
+                       case glyph_data_subpix:
+                               fScanlineStorageSubpix.serialize(data);
+                               break;
 
                        case glyph_data_outline: 
                                fPath.serialize(data);
@@ -570,6 +739,10 @@
                case glyph_ren_native_gray8:
                        fGlyphRendering = glyph_ren_native_gray8;
                        break;
+                       
+               case glyph_ren_subpix:
+                       fGlyphRendering = glyph_ren_subpix;
+                       break;
 
                case glyph_ren_outline:
                        if (FT_IS_SCALABLE(fFace))
@@ -580,7 +753,7 @@
        }
 
        FT_Set_Pixel_Sizes(fFace,
-               unsigned(size * 64.0) >> 6,             // pixel_width
+               (unsigned(size * 64.0) >> 6),           // pixel_width
                unsigned(size * 64.0) >> 6);    // pixel_height
 
        if (charMap != FT_ENCODING_NONE) {
Index: src/servers/app/agg_scanline_storage_subpix.h
===================================================================
--- src/servers/app/agg_scanline_storage_subpix.h       (revision 0)
+++ src/servers/app/agg_scanline_storage_subpix.h       (revision 0)
@@ -0,0 +1,682 @@
+/*
+ * Copyright 2008, Andrej Spielmann <andrej.spielmann@xxxxxxxxxxxx>.
+ * All rights reserved. Distributed under the terms of the MIT License.
+ *
+ * Copyright 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
+ *
+ *
+ * Class scanline_storage_subpix, a slightly modified version of
+ * scanline_storage customized to store 3 covers per pixel
+ *
+ */
+
+#ifndef AGG_SCANLINE_STORAGE_SUBPIX_INCLUDED
+#define AGG_SCANLINE_STORAGE_SUBPIX_INCLUDED
+
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+#include "agg_array.h"
+#include "agg_scanline_storage_aa.h"
+
+
+namespace agg
+{
+    //--------------------------------------------scanline_storage_subpix
+    template<class T> 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<class Scanline> 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<class Scanline> 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<T>      m_covers;
+        pod_bvector<span_data, 10>    m_spans;
+        pod_bvector<scanline_data, 8> 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<int8u>  scanline_storage_subpix8;  
//--------scanline_storage_subpix8
+    typedef scanline_storage_subpix<int16u> scanline_storage_subpix16; 
//--------scanline_storage_subpix16
+    typedef scanline_storage_subpix<int32u> scanline_storage_subpix32; 
//--------scanline_storage_subpix32
+
+
+    //--------------------------------------serialized_scanlines_adaptor_subpix
+    template<class T> 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<class Scanline> 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<int8u>
+    serialized_scanlines_adaptor_subpix8; 
//serialized_scanlines_adaptor_subpix8
+    
+    typedef serialized_scanlines_adaptor_subpix<int16u>
+    serialized_scanlines_adaptor_subpix16; 
//serialized_scanlines_adaptor_subpix16
+    
+    typedef serialized_scanlines_adaptor_subpix<int32u>
+    serialized_scanlines_adaptor_subpix32; 
//serialized_scanlines_adaptor_subpix32
+
+}
+
+
+#endif
+
Index: src/servers/app/ServerApp.cpp
===================================================================
--- src/servers/app/ServerApp.cpp       (revision 26239)
+++ src/servers/app/ServerApp.cpp       (working copy)
@@ -9,6 +9,7 @@
  *             Stefano Ceccherini (burton666@xxxxxxxxx)
  *             Axel Dörfler, axeld@xxxxxxxxxxxxxxxx
  *             Jérôme Duval, jerome.duval@xxxxxxx
+ *             Andrej Spielmann, <andrej.spielmann@xxxxxxxxxxxx>
  */
 
 /*!
@@ -2534,6 +2535,46 @@
                        fLink.Flush();
                        break;
                }
+               
+               case AS_SET_FONT_SUBPIXEL_ANTIALIASING:
+               {
+                       bool subpix;
+                       if (link.Read<bool>(&subpix) == B_OK) {
+                               LockedDesktopSettings settings(fDesktop);
+                               settings.SetFontSubpixelAntialiasing(subpix);
+                       }
+                       fDesktop->Redraw();
+                       break;
+               }
+               
+               case AS_GET_FONT_SUBPIXEL_ANTIALIASING:
+               {
+                       DesktopSettings settings(fDesktop);
+                       fLink.StartMessage(B_OK);
+                       fLink.Attach<bool>(settings.FontSubpixelAntialiasing());
+                       fLink.Flush();
+                       break;
+               }
+               
+               case AS_SET_HINTING:
+               {
+                       bool hinting;
+                       if (link.Read<bool>(&hinting) == B_OK) {
+                               LockedDesktopSettings settings(fDesktop);
+                               settings.SetHinting(hinting);
+                       }
+                       fDesktop->Redraw();
+                       break;
+               }
+               
+               case AS_GET_HINTING:
+               {
+                       DesktopSettings settings(fDesktop);
+                       fLink.StartMessage(B_OK);
+                       fLink.Attach<bool>(settings.Hinting());
+                       fLink.Flush();
+                       break;
+               }
 
                default:
                        printf("ServerApp %s received unhandled message code 
%ld\n",
Index: src/servers/app/FontCacheEntry.h
===================================================================
--- src/servers/app/FontCacheEntry.h    (revision 26239)
+++ src/servers/app/FontCacheEntry.h    (working copy)
@@ -5,6 +5,7 @@
  * Authors:
  *             Maxim Shemanarev <mcseemagg@xxxxxxxxx>
  *             Stephan Aßmus <superstippi@xxxxxx>
+ *             Andrej Spielmann, <andrej.spielmann@xxxxxxxxxxxx>
  */
 
 //----------------------------------------------------------------------------
@@ -60,6 +61,7 @@
        typedef GlyphGray8Adapter::embedded_scanline    GlyphGray8Scanline;
        typedef FontEngine::MonoAdapter                                 
GlyphMonoAdapter;
        typedef GlyphMonoAdapter::embedded_scanline             
GlyphMonoScanline;
+       typedef FontEngine::SubpixAdapter                               
SubpixAdapter;
        typedef agg::conv_curve<GlyphPathAdapter>               CurveConverter;
        typedef agg::conv_contour<CurveConverter>               
ContourConverter;
 
@@ -92,6 +94,13 @@
 
        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();
@@ -110,6 +119,8 @@
 
                        GlyphCachePool*         fGlyphCache;
                        FontEngine                      fEngine;
+       static  glyph_rendering         sDefaultRenderType;
+       static  bool                            sDefaultHinting;
 
        static  BLocker                         sUsageUpdateLock;
                        bigtime_t                       fLastUsedTime;
Index: src/servers/app/FontEngine.h
===================================================================
--- src/servers/app/FontEngine.h        (revision 26239)
+++ src/servers/app/FontEngine.h        (working copy)
@@ -5,6 +5,7 @@
  * Authors:
  *             Maxim Shemanarev <mcseemagg@xxxxxxxxx>
  *             Stephan Aßmus <superstippi@xxxxxx>
+ *             Andrej Spielmann, <andrej.spielmann@xxxxxxxxxxxx>
  */
 
 //----------------------------------------------------------------------------
@@ -39,11 +40,15 @@
 #include <agg_conv_curve.h>
 #include <agg_trans_affine.h>
 
+#include "agg_scanline_storage_subpix.h"
+#include "agg_scanline_u_subpix.h"
 
+
 enum glyph_rendering {
        glyph_ren_native_mono,
        glyph_ren_native_gray8,
        glyph_ren_outline,
+       glyph_ren_subpix
 };
 
 
@@ -51,15 +56,18 @@
        glyph_data_invalid      = 0,
        glyph_data_mono         = 1,
        glyph_data_gray8        = 2,
-       glyph_data_outline      = 3
+       glyph_data_outline      = 3,
+       glyph_data_subpix   = 4
 };
 
 
 class FontEngine {
  public:
+       typedef agg::serialized_scanlines_adaptor_subpix<uint8> SubpixAdapter;
        typedef agg::serialized_scanlines_adaptor_aa<uint8>             
Gray8Adapter;
        typedef agg::serialized_scanlines_adaptor_bin                   
MonoAdapter;
        typedef agg::scanline_storage_aa8                                       
        ScanlineStorageAA;
+       typedef agg::scanline_storage_subpix8                                   
ScanlineStorageSubpix;
        typedef agg::scanline_storage_bin                                       
        ScanlineStorageBin;
        typedef agg::serialized_integer_path_adaptor<int32, 6>  PathAdapter;
 
@@ -139,9 +147,11 @@
                        CurveConverterType      fCurves;
                        agg::scanline_u8        fScanlineAA;
                        agg::scanline_bin       fScanlineBin;
+                       agg::scanline_u8_subpix fScanlineSubpix;
                
                        ScanlineStorageAA       fScanlineStorageAA;
                        ScanlineStorageBin      fScanlineStorageBin;
+                       ScanlineStorageSubpix fScanlineStorageSubpix;
 };
 
 
Index: src/servers/app/drawing/Painter/AGGTextRenderer.h
===================================================================
--- src/servers/app/drawing/Painter/AGGTextRenderer.h   (revision 26239)
+++ src/servers/app/drawing/Painter/AGGTextRenderer.h   (working copy)
@@ -1,6 +1,7 @@
 /*
- * Copyright 2005-2007, Stephan Aßmus <superstippi@xxxxxx>. All rights 
reserved.
- * Distributed under the terms of the MIT License.
+ * Copyright 2005-2007, Stephan Aßmus <superstippi@xxxxxx>.
+ * Copyright 2008, Andrej Spielmann <andrej.spielmann@xxxxxxxxxxxx>.
+ * All rights reserved. Distributed under the terms of the MIT License.
  */
 #ifndef AGG_TEXT_RENDERER_H
 #define AGG_TEXT_RENDERER_H
@@ -21,7 +22,8 @@
 
 class AGGTextRenderer {
  public:
-                                                               
AGGTextRenderer(renderer_type& solidRenderer,
+                                                               
AGGTextRenderer(renderer_subpix_type& subpixRenderer,
+                                                                       
renderer_type& solidRenderer,
                                                                        
renderer_bin_type& binRenderer,
                                                                        
scanline_unpacked_type& scanline);
        virtual                                         ~AGGTextRenderer();
@@ -62,12 +64,14 @@
        FontCacheEntry::GlyphGray8Scanline      fGray8Scanline;
        FontCacheEntry::GlyphMonoAdapter        fMonoAdaptor;
        FontCacheEntry::GlyphMonoScanline       fMonoScanline;
+       FontCacheEntry::SubpixAdapter           fSubpixAdaptor;
 
        FontCacheEntry::CurveConverter          fCurves;
        FontCacheEntry::ContourConverter        fContour;
 
        renderer_type&                          fSolidRenderer;
        renderer_bin_type&                      fBinRenderer;
+       renderer_subpix_type&           fSubpixRenderer;
        scanline_unpacked_type&         fScanline;
        rasterizer_type                         fRasterizer;
                // NOTE: the object has it's own rasterizer object
Index: src/servers/app/drawing/Painter/agg_renderer_scanline_subpix.h
===================================================================
--- src/servers/app/drawing/Painter/agg_renderer_scanline_subpix.h      
(revision 0)
+++ src/servers/app/drawing/Painter/agg_renderer_scanline_subpix.h      
(revision 0)
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2008, Andrej Spielmann <andrej.spielmann@xxxxxxxxxxxx>.
+ * All rights reserved. Distributed under the terms of the MIT License.
+ *
+ * Copyright 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
+ *
+ *
+ */
+
+#include <Region.h>
+
+#include "agg_basics.h"
+#include "agg_array.h"
+#include "agg_renderer_base.h"
+#include "agg_renderer_scanline.h"
+
+
+namespace agg
+{
+
+    //============================================render_scanline_subpix_solid
+    template<class Scanline, class BaseRenderer, class ColorT> 
+    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;
+        }
+    }
+
+
+    //==========================================renderer_scanline_subpix_solid
+    template<class BaseRenderer> 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;
+        }
+        
+        //--------------------------------------------------------------------
+        void color(const color_type& c) { m_color = c; }
+        const color_type& color() const { return m_color; }
+
+        //--------------------------------------------------------------------
+        void prepare() {}
+
+        //--------------------------------------------------------------------
+        template<class Scanline> void render(const Scanline& sl)
+        {
+            render_scanline_subpix_solid(sl, *m_ren, m_color);
+        }
+        
+    private:
+        base_ren_type* m_ren;
+        color_type m_color;
+    };
+
+}
Index: src/servers/app/drawing/Painter/drawing_modes/DrawingModeBlendSUBPIX.h
===================================================================
--- src/servers/app/drawing/Painter/drawing_modes/DrawingModeBlendSUBPIX.h      
(revision 0)
+++ src/servers/app/drawing/Painter/drawing_modes/DrawingModeBlendSUBPIX.h      
(revision 0)
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2005, Stephan Aßmus <superstippi@xxxxxx>.
+ * Copyright 2008, Andrej Spielmann <andrej.spielmann@xxxxxxxxxxxx>.
+ * All rights reserved. Distributed under the terms of the MIT License.
+ *
+ * DrawingMode implementing B_OP_ADD on B_RGBA32.
+ *
+ */
+
+#ifndef DRAWING_MODE_BLEND_SUBPIX_H
+#define DRAWING_MODE_BLEND_SUBPIX_H
+
+#include "DrawingMode.h"
+
+
+// BLEND_BLEND_SUBPIX
+#define BLEND_BLEND_SUBPIX(d, r, g, b, a1, a2, a3) \
+{ \
+       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_SUBPIX(d, rt, gt, bt, a1, a2, a3); \
+}
+
+// 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++;
+               } while(--len);
+       } else {
+               do {
+                       rgb_color color = pattern->ColorAt(x, y);
+
+                       BLEND_BLEND(p, color.red, color.green, color.blue, 
cover);
+
+                       x++;
+                       p += 4;
+                       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);
+       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 += 3;
+               p += 4;
+               x++;
+               len -= 3;
+       } while(len);
+}
+
+
+#endif // DRAWING_MODE_BLEND_SUBPIX_H
+
Index: src/servers/app/drawing/Painter/drawing_modes/DrawingModeSubtractSUBPIX.h
===================================================================
--- src/servers/app/drawing/Painter/drawing_modes/DrawingModeSubtractSUBPIX.h   
(revision 0)
+++ src/servers/app/drawing/Painter/drawing_modes/DrawingModeSubtractSUBPIX.h   
(revision 0)
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2005, Stephan Aßmus <superstippi@xxxxxx>.
+ * Copyright 2008, Andrej Spielmann <andrej.spielmann@xxxxxxxxxxxx>.
+ * All rights reserved. Distributed under the terms of the MIT License.
+ *
+ * DrawingMode implementing B_OP_SUBTRACT on B_RGBA32.
+ *
+ */
+
+#ifndef DRAWING_MODE_SUBTRACT_SUBPIX_H
+#define DRAWING_MODE_SUBTRACT_SUBPIX_H
+
+#include <SupportDefs.h>
+
+#include "DrawingMode.h"
+#include "PatternHandler.h"
+
+// BLEND_SUBTRACT_SUBPIX
+#define BLEND_SUBTRACT_SUBPIX(d, r, g, b, a1, a2, a3) \
+{ \
+       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_SUBPIX(d, rt, gt, bt, a1, a2, a3); \
+}
+
+// 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, 
+                                                  const color_type& c, const 
uint8* covers,
+                                                  agg_buffer* buffer, const 
PatternHandler* pattern)
+{
+       uint8* p = buffer->row_ptr(y) + (x << 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 += 3;
+               p += 4;
+               x++;
+               len -= 3;
+       } while(len);
+}
+
+#endif // DRAWING_MODE_SUBTRACT_SUBPIX_H
+
Index: 
src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaCOSolidSUBPIX.h
===================================================================
--- 
src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaCOSolidSUBPIX.h   
    (revision 0)
+++ 
src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaCOSolidSUBPIX.h   
    (revision 0)
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2005, Stephan Aßmus <superstippi@xxxxxx>.
+ * Copyright 2008, Andrej Spielmann <andrej.spielmann@xxxxxxxxxxxx>.
+ * All rights reserved. Distributed under the terms of the MIT License.
+ *
+ * DrawingMode implementing B_OP_ALPHA in "Constant Overlay" mode on B_RGBA32.
+ *
+ */
+
+#ifndef DRAWING_MODE_ALPHA_CO_SOLID_SUBPIX_H
+#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);
+               }
+       }
+}
+
+// blend_solid_hspan_alpha_co_solid_subpix
+void
+blend_solid_hspan_alpha_co_solid_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);
+       uint8 hAlpha = pattern->HighColor().alpha;
+       uint16 alphaRed;
+       uint16 alphaGreen;
+       uint16 alphaBlue;
+       do {
+               alphaRed = hAlpha * covers[0];
+               alphaGreen = hAlpha * covers[1];
+               alphaBlue = hAlpha * covers[2];
+               BLEND_ALPHA_CO_SUBPIX(p, c.r, c.g, c.b, 
+                                                               alphaBlue, 
alphaGreen, alphaRed);
+               covers += 3;
+               p += 4;
+               x++;
+               len -= 3;
+       } while(len);
+}
+
+
+#endif // DRAWING_MODE_ALPHA_CO_SOLID_SUBPIX_H
+
Index: src/servers/app/drawing/Painter/drawing_modes/DrawingModeInvertSUBPIX.h
===================================================================
--- src/servers/app/drawing/Painter/drawing_modes/DrawingModeInvertSUBPIX.h     
(revision 0)
+++ src/servers/app/drawing/Painter/drawing_modes/DrawingModeInvertSUBPIX.h     
(revision 0)
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2005, Stephan Aßmus <superstippi@xxxxxx>.
+ * Copyright 2008, Andrej Spielmann <andrej.spielmann@xxxxxxxxxxxx>.
+ * All rights reserved. Distributed under the terms of the MIT License.
+ *
+ * DrawingMode implementing B_OP_INVERT on B_RGBA32.
+ *
+ */
+
+#ifndef DRAWING_MODE_INVERT_SUBPIX_H
+#define DRAWING_MODE_INVERT_SUBPIX_H
+
+#include "DrawingMode.h"
+
+// BLEND_INVERT_SUBPIX
+#define BLEND_INVERT_SUBPIX(d, a1, a2, a3) \
+{ \
+       pixel32 _p; \
+       _p.data32 = *(uint32*)d; \
+       BLEND_SUBPIX(d, 255 - _p.data8[2], 255 - _p.data8[1], 255 - 
_p.data8[0], \
+                                       a1, a2, a3); \
+}
+
+// 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);
+       do {
+               if (pattern->IsHighColor(x, y)) {
+                       BLEND_INVERT_SUBPIX(p, covers[2], covers[1], covers[0]);
+               }
+               covers += 3;
+               p += 4;
+               x++;
+               len -= 3;
+       } while(len);
+}
+
+
+#endif // DRAWING_MODE_INVERT_SUBPIX_H
+
Index: src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPCSUBPIX.h
===================================================================
--- src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPCSUBPIX.h    
(revision 0)
+++ src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPCSUBPIX.h    
(revision 0)
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2005, Stephan Aßmus <superstippi@xxxxxx>.
+ * Copyright 2008, Andrej Spielmann <andrej.spielmann@xxxxxxxxxxxx>.
+ * All rights reserved. Distributed under the terms of the MIT License.
+ *
+ * DrawingMode implementing B_OP_ALPHA in "Pixel Composite" mode on B_RGBA32.
+ *
+ */
+
+#ifndef DRAWING_MODE_ALPHA_PC_SUBPIX_H
+#define DRAWING_MODE_ALPHA_PC_SUBPIX_H
+
+#include "DrawingMode.h"
+
+// BLEND_ALPHA_PC_SUBPIX
+#define BLEND_ALPHA_PC_SUBPIX(d, r, g, b, a1, a2, a3) \
+{ \
+       BLEND_COMPOSITE16_SUBPIX(d, r, g, b, a1, a2, a3); \
+}
+
+// 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, 
+                                                  const color_type& c, const 
uint8* covers,
+                                                  agg_buffer* buffer, const 
PatternHandler* pattern)
+{
+       uint8* p = buffer->row_ptr(y) + (x << 2);
+       uint16 alphaRed;
+       uint16 alphaGreen;
+       uint16 alphaBlue;
+       do {
+               rgb_color color = pattern->ColorAt(x, y);
+               alphaRed = color.alpha * covers[0];
+               alphaGreen = color.alpha * covers[1];
+               alphaBlue = color.alpha * covers[2];            
+               BLEND_ALPHA_PC_SUBPIX(p, color.red, color.green, color.blue,
+                                                               alphaBlue, 
alphaGreen, alphaRed);
+               covers += 3;
+               p += 4;
+               x++;
+               len -= 3;
+       } while(len);
+}
+
+#endif // DRAWING_MODE_ALPHA_PC_SUBPIX_H
+
Index: src/servers/app/drawing/Painter/drawing_modes/DrawingModeOverSUBPIX.h
===================================================================
--- src/servers/app/drawing/Painter/drawing_modes/DrawingModeOverSUBPIX.h       
(revision 0)
+++ src/servers/app/drawing/Painter/drawing_modes/DrawingModeOverSUBPIX.h       
(revision 0)
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2005, Stephan Aßmus <superstippi@xxxxxx>.
+ * Copyright 2008, Andrej Spielmann <andrej.spielmann@xxxxxxxxxxxx>.
+ * All rights reserved. Distributed under the terms of the MIT License.
+ *
+ * DrawingMode implementing B_OP_OVER on B_RGBA32.
+ *
+ */
+
+#ifndef DRAWING_MODE_OVER_SUBPIX_H
+#define DRAWING_MODE_OVER_SUBPIX_H
+
+#include "DrawingMode.h"
+
+// BLEND_OVER_SUBPIX
+#define BLEND_OVER_SUBPIX(d, r, g, b, a1, a2, a3) \
+{ \
+       BLEND_SUBPIX(d, r, g, b, a1, a2, a3) \
+}
+
+// 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 > 0);
+       }
+}
+
+// blend_solid_hspan_over_subpix
+void
+blend_solid_hspan_over_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);
+       rgb_color color = pattern->HighColor();
+       do {
+               if (pattern->IsHighColor(x, y)) {
+                       BLEND_OVER_SUBPIX(p, color.red, color.green, color.blue,
+                                                               covers[2], 
covers[1], covers[0]);
+               }
+               covers += 3;
+               p += 4;
+               x++;
+               len -= 3;
+       } while(len);
+}
+
+#endif // DRAWING_MODE_OVER_SUBPIX_H
+
Index: src/servers/app/drawing/Painter/drawing_modes/PixelFormat.h
===================================================================
--- src/servers/app/drawing/Painter/drawing_modes/PixelFormat.h (revision 26239)
+++ src/servers/app/drawing/Painter/drawing_modes/PixelFormat.h (working copy)
@@ -1,6 +1,7 @@
 /*
- * Copyright 2005, Stephan Aßmus <superstippi@xxxxxx>. All rights reserved.
- * Distributed under the terms of the MIT License.
+ * Copyright 2005, Stephan Aßmus <superstippi@xxxxxx>. 
+ * Copyright 2008, Andrej Spielmann <andrej.spielmann@xxxxxxxxxxxx>
+ * All rights reserved. Distributed under the terms of the MIT License.
  *
  * Copyright 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
  *
@@ -103,6 +104,11 @@
                                                                                
        unsigned len,
                                                                                
        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,
@@ -113,6 +119,11 @@
                                                                                
                  unsigned len,
                                                                                
                  const color_type& c,
                                                                                
                  const uint8* covers);
+                                                                               
                  
+       inline  void                            blend_solid_hspan_subpix(int x, 
int y,
+                                                                               
                  unsigned len,
+                                                                               
                  const color_type& c,
+                                                                               
                  const uint8* covers);
 
        inline  void                            blend_solid_vspan(int x, int y,
                                                                                
                  unsigned len,
@@ -138,8 +149,10 @@
 
        blend_pixel_f                           fBlendPixel;
        blend_line                                      fBlendHLine;
+       blend_line                                      fBlendHLineSubpix;
        blend_line                                      fBlendVLine;
        blend_solid_span                        fBlendSolidHSpan;
+       blend_solid_span            fBlendSolidHSpanSubpix;
        blend_solid_span                        fBlendSolidVSpan;
        blend_color_span                        fBlendColorHSpan;
        blend_color_span                        fBlendColorVSpan;
@@ -198,6 +211,14 @@
        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,
@@ -214,6 +235,14 @@
        fBlendSolidHSpan(x, y, len, c, covers, fBuffer, fPatternHandler);
 }
 
+// blend_solid_hspan_subpix
+inline void
+PixelFormat::blend_solid_hspan_subpix(int x, int y, unsigned len, 
+                                                          const color_type& c, 
const uint8* covers)
+{
+       fBlendSolidHSpanSubpix(x, y, len, c, covers, fBuffer, fPatternHandler);
+}
+
 // blend_solid_vspan
 inline void
 PixelFormat::blend_solid_vspan(int x, int y, unsigned len, 
Index: src/servers/app/drawing/Painter/drawing_modes/DrawingModeSelectSUBPIX.h
===================================================================
--- src/servers/app/drawing/Painter/drawing_modes/DrawingModeSelectSUBPIX.h     
(revision 0)
+++ src/servers/app/drawing/Painter/drawing_modes/DrawingModeSelectSUBPIX.h     
(revision 0)
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2005, Stephan Aßmus <superstippi@xxxxxx>.
+ * Copyright 2008, Andrej Spielmann <andrej.spielmann@xxxxxxxxxxxx>.
+ * All rights reserved. Distributed under the terms of the MIT License.
+ *
+ * DrawingMode implementing B_OP_SELECT on B_RGBA32.
+ *
+ */
+
+#ifndef DRAWING_MODE_SELECT_SUBPIX_H
+#define DRAWING_MODE_SELECT_SUBPIX_H
+
+#include "DrawingMode.h"
+
+// BLEND_SELECT_SUBPIX
+#define BLEND_SELECT_SUBPIX(d, r, g, b, a1, a2, a3) \
+{ \
+       BLEND_SUBPIX(d, r, g, b, a1, a2, a3); \
+}
+
+// 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, const 
uint8* covers,
+                                                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;
+       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 += 3;
+               p += 4;
+               x++;
+               len -= 3;
+       } while(len);
+}
+
+#endif // DRAWING_MODE_SELECT_SUBPIX_H
+
Index: 
src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPOSolidSUBPIX.h
===================================================================
--- 
src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPOSolidSUBPIX.h   
    (revision 0)
+++ 
src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPOSolidSUBPIX.h   
    (revision 0)
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2005, Stephan Aßmus <superstippi@xxxxxx>.
+ * Copyright 2008, Andrej Spielmann <andrej.spielmann@xxxxxxxxxxxx>.
+ * All rights reserved. Distributed under the terms of the MIT License.
+ *
+ * DrawingMode implementing B_OP_ALPHA in "Constant Overlay" mode on B_RGBA32.
+ *
+ */
+
+#ifndef DRAWING_MODE_ALPHA_PO_SOLID_SUBPIX_H
+#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);
+               }
+       }
+}
+
+// blend_solid_hspan_alpha_po_solid_subpix
+void
+blend_solid_hspan_alpha_po_solid_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);
+       uint16 alphaRed;
+       uint16 alphaGreen;
+       uint16 alphaBlue;
+       do {
+               alphaRed = c.a * covers[0];
+               alphaGreen = c.a * covers[1];
+               alphaBlue = c.a * covers[2];
+               BLEND_ALPHA_PO_SUBPIX(p, c.r, c.g, c.b,
+                                                               alphaBlue, 
alphaGreen, alphaRed);
+               covers += 3;
+               p += 4;
+               x++;
+               len -= 3;
+       } while(len);
+}
+
+#endif // DRAWING_MODE_ALPHA_PO_SOLID_SUBPIX_H
+
Index: src/servers/app/drawing/Painter/drawing_modes/DrawingModeCopyTextSUBPIX.h
===================================================================
--- src/servers/app/drawing/Painter/drawing_modes/DrawingModeCopyTextSUBPIX.h   
(revision 0)
+++ src/servers/app/drawing/Painter/drawing_modes/DrawingModeCopyTextSUBPIX.h   
(revision 0)
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2006, Stephan Aßmus <superstippi@xxxxxx>.
+ * Copyright 2008, Andrej Spielmann <andrej.spielmann@xxxxxxxxxxxx>.
+ * All rights reserved. Distributed under the terms of the MIT License.
+ *
+ * DrawingMode implementing B_OP_COPY for text on B_RGBA32.
+ *
+ */
+
+#ifndef DRAWING_MODE_COPY_TEXT_SUBPIX_H
+#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);
+       }
+}
+
+// blend_solid_hspan_copy_text_subpix
+void
+blend_solid_hspan_copy_text_subpix(int x, int y, unsigned len, 
+                                                        const color_type& c, 
const uint8* covers,
+                                                        agg_buffer* buffer,
+                                                        const PatternHandler* 
pattern)
+{
+//printf("blend_solid_hspan_copy_text(%d, %d)\n", x, len);
+       uint8* p = buffer->row_ptr(y) + (x << 2);
+       //rgb_color l = pattern->LowColor();
+       do {
+               BLEND_OVER_SUBPIX(p, c.r, c.g, c.b, covers[2], covers[1], 
covers[0]);
+               covers += 3;
+               p += 4;
+               x++;
+               len -= 3;
+       } while(len);
+}
+
+#endif // DRAWING_MODE_COPY_TEXT_SUBPIX_H
+
Index: src/servers/app/drawing/Painter/drawing_modes/DrawingModeMinSUBPIX.h
===================================================================
--- src/servers/app/drawing/Painter/drawing_modes/DrawingModeMinSUBPIX.h        
(revision 0)
+++ src/servers/app/drawing/Painter/drawing_modes/DrawingModeMinSUBPIX.h        
(revision 0)
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2005, Stephan Aßmus <superstippi@xxxxxx>.
+ * Copyright 2008, Andrej Spielmann <andrej.spielmann@xxxxxxxxxxxx>.
+ * All rights reserved. Distributed under the terms of the MIT License.
+ *
+ * DrawingMode implementing B_OP_MIN on B_RGBA32.
+ *
+ */
+
+#ifndef DRAWING_MODE_MIN_SUBPIX_H
+#define DRAWING_MODE_MIN_SUBPIX_H
+
+#include "DrawingMode.h"
+
+// BLEND_MIN_SUBPIX
+#define BLEND_MIN_SUBPIX(d, r, g, b, a1, a2, a3) \
+{ \
+       pixel32 _p; \
+       _p.data32 = *(uint32*)d; \
+       uint8 rt = min_c(_p.data8[2], (r)); \
+       uint8 gt = min_c(_p.data8[1], (g)); \
+       uint8 bt = min_c(_p.data8[0], (b)); \
+       BLEND_SUBPIX(d, rt, gt, bt, a1, a2, a3); \
+}
+
+// BLEND_MIN
+#define BLEND_MIN(d, r, g, b, a) \
+{ \
+       pixel32 _p; \
+       _p.data32 = *(uint32*)d; \
+       uint8 rt = min_c(_p.data8[2], (r)); \
+       uint8 gt = min_c(_p.data8[1], (g)); \
+       uint8 bt = min_c(_p.data8[0], (b)); \
+       BLEND(d, rt, gt, bt, a); \
+}
+
+// ASSIGN_MIN
+#define ASSIGN_MIN(d, r, g, b) \
+{ \
+       pixel32 _p; \
+       _p.data32 = *(uint32*)d; \
+       d[0] = min_c(_p.data8[0], (b)); \
+       d[1] = min_c(_p.data8[1], (g)); \
+       d[2] = min_c(_p.data8[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);
+       }
+}
+
+// Maybe this would make more sense without any filtering?
+// 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);
+       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 += 3;
+               p += 4;
+               x++;
+               len -= 3;
+       } while(len);
+}
+
+#endif // DRAWING_MODE_MIN_SUBPIX_H
+
Index: src/servers/app/drawing/Painter/drawing_modes/DrawingMode.h
===================================================================
--- src/servers/app/drawing/Painter/drawing_modes/DrawingMode.h (revision 26239)
+++ src/servers/app/drawing/Painter/drawing_modes/DrawingMode.h (working copy)
@@ -1,6 +1,7 @@
 /*
- * Copyright 2005, Stephan Aßmus <superstippi@xxxxxx>. All rights reserved.
- * Distributed under the terms of the MIT License.
+ * Copyright 2005, Stephan Aßmus <superstippi@xxxxxx>.
+ * Copyright 2008, Andrej Spielmann <andrej.spielmann@xxxxxxxxxxxx>.
+ * All rights reserved. Distributed under the terms of the MIT License.
  *
  * Base class for different drawing modes.
  *
@@ -34,6 +35,16 @@
        d[3] = 255; \
 }
 
+#define BLEND_SUBPIX(d, r, g, b, a1, a2, a3) \
+{ \
+       pixel32 _p; \
+       _p.data32 = *(uint32*)d; \
+       d[0] = (((((b) - _p.data8[0]) * (a1)) + (_p.data8[0] << 8)) >> 8); \
+       d[1] = (((((g) - _p.data8[1]) * (a2)) + (_p.data8[1] << 8)) >> 8); \
+       d[2] = (((((r) - _p.data8[2]) * (a3)) + (_p.data8[2] << 8)) >> 8); \
+       d[3] = 255; \
+}
+
 // BLEND_FROM
 //
 // This macro assumes source alpha in range 0..255 and
@@ -49,6 +60,14 @@
        d[3] = 255; \
 }
 
+#define BLEND_FROM_SUBPIX(d, r1, g1, b1, r2, g2, b2, a1, a2, a3) \
+{ \
+       d[0] = (((((b2) - (b1)) * (a1)) + ((b1) << 8)) >> 8); \
+       d[1] = (((((g2) - (g1)) * (a2)) + ((g1) << 8)) >> 8); \
+       d[2] = (((((r2) - (r1)) * (a3)) + ((r1) << 8)) >> 8); \
+       d[3] = 255; \
+}
+
 // BLEND16
 //
 // This macro assumes source alpha in range 0..65025 and
@@ -65,8 +84,17 @@
        d[3] = 255; \
 }
 
+// BLEND16_SUBPIX
+#define BLEND16_SUBPIX(d, r, g, b, a1, a2, a3) \
+{ \
+       pixel32 _p; \
+       _p.data32 = *(uint32*)d; \
+       d[0] = (((((b) - _p.data8[0]) * (a1)) + (_p.data8[0] << 16)) >> 16); \
+       d[1] = (((((g) - _p.data8[1]) * (a2)) + (_p.data8[1] << 16)) >> 16); \
+       d[2] = (((((r) - _p.data8[2]) * (a3)) + (_p.data8[2] << 16)) >> 16); \
+       d[3] = 255; \
+}
 
-
 // BLEND_COMPOSITE
 //
 // This macro assumes source alpha in range 0..255 and
@@ -99,6 +127,43 @@
        } \
 }
 
+// BLEND_COMPOSITE_SUBPIX
+#define BLEND_COMPOSITE_SUBPIX(d, r, g, b, a1, a2, a3) \
+{ \
+       pixel32 _p; \
+       _p.data32 = *(uint32*)d; \
+       if (_p.data8[3] == 255) { \
+               d[0] = (((((b) - _p.data8[0]) * (a1)) + (_p.data8[0] << 8)) >> 
8); \
+               d[1] = (((((g) - _p.data8[1]) * (a2)) + (_p.data8[1] << 8)) >> 
8); \
+               d[2] = (((((r) - _p.data8[2]) * (a3)) + (_p.data8[2] << 8)) >> 
8); \
+               d[3] = 255; \
+       } else { \
+               if (_p.data8[3] == 0) { \
+                       d[0] = (b); \
+                       d[1] = (g); \
+                       d[2] = (r); \
+                       d[3] = (a1 + a2 + a3)/3; \
+               } else { \
+                       uint8 alphaRest1 = 255 - (a1); \
+                       uint8 alphaRest2 = 255 - (a2); \
+                       uint8 alphaRest3 = 255 - (a3); \
+                       uint32 alphaTemp1 = (65025 - alphaRest1 * (255 - 
_p.data8[3])); \
+                       uint32 alphaTemp2 = (65025 - alphaRest2 * (255 - 
_p.data8[3])); \
+                       uint32 alphaTemp3 = (65025 - alphaRest3 * (255 - 
_p.data8[3])); \
+                       uint32 alphaDest1 = _p.data8[3] * alphaRest1; \
+                       uint32 alphaDest2 = _p.data8[3] * alphaRest2; \
+                       uint32 alphaDest3 = _p.data8[3] * alphaRest3; \
+                       uint32 alphaSrc1 = 255 * (a1); \
+                       uint32 alphaSrc2 = 255 * (a2); \
+                       uint32 alphaSrc3 = 255 * (a3); \
+                       d[0] = (_p.data8[0] * alphaDest1 + (b) * alphaSrc1) / 
alphaTemp1; \
+                       d[1] = (_p.data8[1] * alphaDest2 + (g) * alphaSrc2) / 
alphaTemp2; \
+                       d[2] = (_p.data8[2] * alphaDest3 + (r) * alphaSrc3) / 
alphaTemp3; \
+                       d[3] = (alphaTemp1 + alphaTemp2 + alphaTemp3)/765; \
+               } \
+       } \
+}
+
 // BLEND_COMPOSITE16
 //
 // This macro assumes source alpha in range 0..65025 and
@@ -110,6 +175,14 @@
        BLEND_COMPOSITE(d, r, g, b, _a); \
 }
 
+// BLEND_COMPOSITE16_SUBPIX
+#define BLEND_COMPOSITE16_SUBPIX(d, r, g, b, a1, a2, a3) \
+{ \
+       uint16 _a1 = (a1) / 255; \
+       uint16 _a2 = (a2) / 255; \
+       uint16 _a3 = (a3) / 255; \
+       BLEND_COMPOSITE_SUBPIX(d, r, g, b, _a1, _a2, _a3); \
+}
 
 static inline
 uint8
@@ -121,6 +194,5 @@
        return uint8((308 * red + 600 * green + 116 * blue) / 1024);
 }
 
-
 #endif // DRAWING_MODE_H
 
Index: src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPOSUBPIX.h
===================================================================
--- src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPOSUBPIX.h    
(revision 0)
+++ src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPOSUBPIX.h    
(revision 0)
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2005, Stephan Aßmus <superstippi@xxxxxx>.
+ * Copyright 2008, Andrej Spielmann <andrej.spielmann@xxxxxxxxxxxx>.
+ * All rights reserved. Distributed under the terms of the MIT License.
+ *
+ * DrawingMode implementing B_OP_ALPHA in "Constant Overlay" mode on B_RGBA32.
+ *
+ */
+
+#ifndef DRAWING_MODE_ALPHA_PO_SUBPIX_H
+#define DRAWING_MODE_ALPHA_PO_SUBPIX_H
+
+#include "DrawingMode.h"
+
+// BLEND_ALPHA_PO_SUBPIX
+#define BLEND_ALPHA_PO_SUBPIX(d, r, g, b, a1, a2, a3) \
+{ \
+       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
+blend_solid_hspan_alpha_po_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);
+       uint16 alphaRed;
+       uint16 alphaGreen;
+       uint16 alphaBlue;
+       do {
+               rgb_color color = pattern->ColorAt(x, y);
+               alphaRed = color.alpha * covers[0];
+               alphaGreen = color.alpha * covers[1];
+               alphaBlue = color.alpha * covers[2];
+               BLEND_ALPHA_PO_SUBPIX(p, color.red, color.green, color.blue,
+                                                               alphaBlue, 
alphaGreen, alphaRed);
+               covers += 3;
+               p += 4;
+               x++;
+               len -= 3;
+       } while(len);
+}
+
+#endif // DRAWING_MODE_ALPHA_PO_SUBPIX_H
+
Index: src/servers/app/drawing/Painter/drawing_modes/DrawingModeMaxSUBPIX.h
===================================================================
--- src/servers/app/drawing/Painter/drawing_modes/DrawingModeMaxSUBPIX.h        
(revision 0)
+++ src/servers/app/drawing/Painter/drawing_modes/DrawingModeMaxSUBPIX.h        
(revision 0)
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2005, Stephan Aßmus <superstippi@xxxxxx>.
+ * Copyright 2008, Andrej Spielmann <andrej.spielmann@xxxxxxxxxxxx>.
+ * All rights reserved. Distributed under the terms of the MIT License.
+ *
+ * DrawingMode implementing B_OP_MAX on B_RGBA32.
+ *
+ */
+
+#ifndef DRAWING_MODE_MAX_SUBPIX_H
+#define DRAWING_MODE_MAX_SUBPIX_H
+
+#include "DrawingMode.h"
+
+// BLEND_MAX_SUBPIX
+#define BLEND_MAX_SUBPIX(d, r, g, b, a1, a2, a3) \
+{ \
+       pixel32 _p; \
+       _p.data32 = *(uint32*)d; \
+       uint8 rt = max_c(_p.data8[2], (r)); \
+       uint8 gt = max_c(_p.data8[1], (g)); \
+       uint8 bt = max_c(_p.data8[0], (b)); \
+       BLEND_SUBPIX(d, rt, gt, bt, a1, a2, a3); \
+}
+
+// BLEND_MAX
+#define BLEND_MAX(d, r, g, b, a) \
+{ \
+       pixel32 _p; \
+       _p.data32 = *(uint32*)d; \
+       uint8 rt = max_c(_p.data8[2], (r)); \
+       uint8 gt = max_c(_p.data8[1], (g)); \
+       uint8 bt = max_c(_p.data8[0], (b)); \
+       BLEND(d, rt, gt, bt, a); \
+}
+
+// ASSIGN_MAX
+#define ASSIGN_MAX(d, r, g, b) \
+{ \
+       pixel32 _p; \
+       _p.data32 = *(uint32*)d; \
+       d[0] = max_c(_p.data8[0], (b)); \
+       d[1] = max_c(_p.data8[1], (g)); \
+       d[2] = max_c(_p.data8[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);
+       }
+}
+
+// Maybe this would make more sense without any filtering?
+// 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);
+       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 += 3;
+               p += 4;
+               x++;
+               len -= 3;
+       } while(len);
+}
+
+#endif // DRAWING_MODE_MAX_SUBPIX_H
+
Index: src/servers/app/drawing/Painter/drawing_modes/DrawingModeAddSUBPIX.h
===================================================================
--- src/servers/app/drawing/Painter/drawing_modes/DrawingModeAddSUBPIX.h        
(revision 0)
+++ src/servers/app/drawing/Painter/drawing_modes/DrawingModeAddSUBPIX.h        
(revision 0)
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2005, Stephan Aßmus <superstippi@xxxxxx>.
+ * Copyright 2008, Andrej Spielmann <andrej.spielmann@xxxxxxxxxxxx>.
+ * All rights reserved. Distributed under the terms of the MIT License.
+ *
+ * DrawingMode implementing B_OP_ADD on B_RGBA32.
+ *
+ */
+
+#ifndef DRAWING_MODE_ADD_SUBPIX_H
+#define DRAWING_MODE_ADD_SUBPIX_H
+
+#include "DrawingMode.h"
+
+
+// BLEND_ADD_SUBPIX
+#define BLEND_ADD_SUBPIX(d, r, g, b, a1, a2, a3) \
+{ \
+       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_SUBPIX(d, rt, gt, bt, a1, a2, a3); \
+}
+
+
+// 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++;
+                       } 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)
+{
+       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 += 3;
+               p += 4;
+               x++;
+               len -= 3;
+       } while(len);
+}
+
+
+#endif // DRAWING_MODE_ADD_SUBPIX_H
+
Index: src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaCCSUBPIX.h
===================================================================
--- src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaCCSUBPIX.h    
(revision 0)
+++ src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaCCSUBPIX.h    
(revision 0)
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2005, Stephan Aßmus <superstippi@xxxxxx>.
+ * Copyright 2008, Andrej Spielmann <andrej.spielmann@xxxxxxxxxxxx>.
+ * All rights reserved. Distributed under the terms of the MIT License.
+ *
+ * DrawingMode implementing B_OP_ALPHA in "Constant Composite" mode on 
B_RGBA32.
+ *
+ */
+
+#ifndef DRAWING_MODE_ALPHA_CC_SUBPIX_H
+#define DRAWING_MODE_ALPHA_CC_SUBPIX_H
+
+#include "DrawingMode.h"
+
+// BLEND_ALPHA_CC_SUBPIX
+#define BLEND_ALPHA_CC_SUBPIX(d, r, g, b, a1, a2, a3) \
+{ \
+       BLEND_COMPOSITE16_SUBPIX(d, r, g, b, a1, a2, a3); \
+}
+
+// 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, 
+                                                  const color_type& c, const 
uint8* covers,
+                                                  agg_buffer* buffer, const 
PatternHandler* pattern)
+{
+       uint8* p = buffer->row_ptr(y) + (x << 2);
+       uint8 hAlpha = pattern->HighColor().alpha;
+       uint16 alphaRed;
+       uint16 alphaGreen;
+       uint16 alphaBlue;
+       do {
+               alphaRed = hAlpha * covers[0];
+               alphaGreen = hAlpha * covers[1];
+               alphaBlue = hAlpha * covers[2];
+               rgb_color color = pattern->ColorAt(x, y);
+               BLEND_ALPHA_CC_SUBPIX(p, color.red, color.green, color.blue,
+                                                               
alphaBlue,alphaGreen, alphaRed);
+               covers += 3;
+               p += 4;
+               x++;
+               len -= 3;
+       } while(len);
+}
+
+#endif // DRAWING_MODE_ALPHA_CC_SUBPIX_H
+
Index: src/servers/app/drawing/Painter/drawing_modes/DrawingModeEraseSUBPIX.h
===================================================================
--- src/servers/app/drawing/Painter/drawing_modes/DrawingModeEraseSUBPIX.h      
(revision 0)
+++ src/servers/app/drawing/Painter/drawing_modes/DrawingModeEraseSUBPIX.h      
(revision 0)
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2005, Stephan Aßmus <superstippi@xxxxxx>.
+ * Copyright 2008, Andrej Spielmann <andrej.spielmann@xxxxxxxxxxxx>.
+ * All rights reserved. Distributed under the terms of the MIT License.
+ *
+ * DrawingMode implementing B_OP_ERASE on B_RGBA32.
+ *
+ */
+
+#ifndef DRAWING_MODE_ERASE_SUBPIX_H
+#define DRAWING_MODE_ERASE_SUBPIX_H
+
+#include "DrawingMode.h"
+
+// BLEND_ERASE_SUBPIX
+#define BLEND_ERASE_SUBPIX(d, r, g, b, a1, a2, a3) \
+{ \
+       BLEND_SUBPIX(d, r, g, b, a1, a2, a3); \
+}
+
+// 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, const 
uint8* covers,
+                                               agg_buffer* buffer, const 
PatternHandler* pattern)
+{
+       uint8* p = buffer->row_ptr(y) + (x << 2);
+       rgb_color color = pattern->LowColor();
+       do {
+               if (pattern->IsHighColor(x, y)) {
+                       BLEND_ERASE_SUBPIX(p, color.red, color.green, 
color.blue, covers[2], covers[1], covers[0]);
+               }
+               covers += 3;
+               p += 4;
+               x++;
+               len -= 3;
+       } while(len);
+}
+
+#endif // DRAWING_MODE_ERASE_SUBPIX_H
+
Index: 
src/servers/app/drawing/Painter/drawing_modes/DrawingModeCopySolidSUBPIX.h
===================================================================
--- src/servers/app/drawing/Painter/drawing_modes/DrawingModeCopySolidSUBPIX.h  
(revision 0)
+++ src/servers/app/drawing/Painter/drawing_modes/DrawingModeCopySolidSUBPIX.h  
(revision 0)
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2005, Stephan Aßmus <superstippi@xxxxxx>.
+ * Copyright 2008, Andrej Spielmann <andrej.spielmann@xxxxxxxxxxxx>.
+ * All rights reserved. Distributed under the terms of the MIT License.
+ *
+ * DrawingMode implementing B_OP_COPY ignoring the pattern (solid) on B_RGBA32.
+ *
+ */
+
+#ifndef DRAWING_MODE_COPY_SOLID_SUBPIX_H
+#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);
+       }
+}
+
+// blend_solid_hspan_copy_solid_subpix
+void
+blend_solid_hspan_copy_solid_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);
+       do {
+               BLEND_OVER_SUBPIX(p, c.r, c.g, c.b, covers[2], covers[1], 
covers[0]);
+               covers += 3;
+               p += 4;
+               x++;
+               len -= 3;
+       } while(len);
+}
+
+#endif // DRAWING_MODE_COPY_SOLID_SUBPIX_H
+
Index: 
src/servers/app/drawing/Painter/drawing_modes/DrawingModeOverSolidSUBPIX.h
===================================================================
--- src/servers/app/drawing/Painter/drawing_modes/DrawingModeOverSolidSUBPIX.h  
(revision 0)
+++ src/servers/app/drawing/Painter/drawing_modes/DrawingModeOverSolidSUBPIX.h  
(revision 0)
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2005, Stephan Aßmus <superstippi@xxxxxx>.
+ * Copyright 2008, Andrej Spielmann <andrej.spielmann@xxxxxxxxxxxx>.
+ * All rights reserved. Distributed under the terms of the MIT License.
+ *
+ * DrawingMode implementing B_OP_OVER on B_RGBA32.
+ *
+ */
+
+#ifndef DRAWING_MODE_OVER_SOLID_SUBPIX_H
+#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);
+       }
+}
+
+// blend_solid_hspan_over_solid_subpix
+void
+blend_solid_hspan_over_solid_subpix(int x, int y, unsigned len, 
+                                                        const color_type& c, 
const uint8* covers,
+                                                        agg_buffer* buffer, 
const PatternHandler* pattern)
+{
+       if (pattern->IsSolidLow())
+               return;
+
+       uint8* p = buffer->row_ptr(y) + (x << 2);
+       do {
+               BLEND_OVER_SUBPIX(p, c.r, c.g, c.b, covers[2], covers[1], 
covers[0]);
+               covers += 3;
+               p += 4;
+               x++;
+               len -= 3;
+       } while(len);
+}
+
+#endif // DRAWING_MODE_OVER_SUBPIX_H
+
Index: src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaCOSUBPIX.h
===================================================================
--- src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaCOSUBPIX.h    
(revision 0)
+++ src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaCOSUBPIX.h    
(revision 0)
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2005, Stephan Aßmus <superstippi@xxxxxx>.
+ * Copyright 2008, Andrej Spielmann <andrej.spielmann@xxxxxxxxxxxx>.
+ * All rights reserved. Distributed under the terms of the MIT License.
+ *
+ * DrawingMode implementing B_OP_ALPHA in "Constant Overlay" mode on B_RGBA32.
+ *
+ */
+
+#ifndef DRAWING_MODE_ALPHA_CO_SUBPIX_H
+#define DRAWING_MODE_ALPHA_CO_SUBPIX_H
+
+#include "DrawingMode.h"
+
+// BLEND_ALPHA_CO_SUBPIX
+#define BLEND_ALPHA_CO_SUBPIX(d, r, g, b, a1, a2, a3) \
+{ \
+       BLEND16_SUBPIX(d, r, g, b, a1, a2, a3); \
+}
+
+// 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, 
+                                                  const color_type& c, const 
uint8* covers,
+                                                  agg_buffer* buffer, const 
PatternHandler* pattern)
+{
+       uint8* p = buffer->row_ptr(y) + (x << 2);
+       uint8 hAlpha = pattern->HighColor().alpha;
+       uint16 alphaRed;
+       uint16 alphaGreen;
+       uint16 alphaBlue;
+       do {
+               alphaRed = hAlpha * covers[0];
+               alphaGreen = hAlpha * covers[1];
+               alphaBlue = hAlpha * covers[2];
+               rgb_color color = pattern->ColorAt(x, y);
+               BLEND_ALPHA_CO_SUBPIX(p, color.red, color.green, color.blue,
+                                                               alphaBlue, 
alphaGreen, alphaRed);
+               covers += 3;
+               p += 4;
+               x++;
+               len -= 3;
+       } while(len);
+}
+
+#endif // DRAWING_MODE_ALPHA_CO_SUBPIX_H
+
Index: src/servers/app/drawing/Painter/drawing_modes/PixelFormat.cpp
===================================================================
--- src/servers/app/drawing/Painter/drawing_modes/PixelFormat.cpp       
(revision 26239)
+++ src/servers/app/drawing/Painter/drawing_modes/PixelFormat.cpp       
(working copy)
@@ -1,6 +1,7 @@
 /*
- * Copyright 2005, Stephan Aßmus <superstippi@xxxxxx>. All rights reserved.
- * Distributed under the terms of the MIT License.
+ * Copyright 2005, Stephan Aßmus <superstippi@xxxxxx>.
+ * Copyright 2008, Andrej Spielmann <andrej.spielmann@xxxxxxxxxxxx>
+ * All rights reserved. Distributed under the terms of the MIT License.
  *
  * Copyright 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
  *
@@ -34,6 +35,26 @@
 #include "DrawingModeSelect.h"
 #include "DrawingModeSubtract.h"
 
+#include "DrawingModeAddSUBPIX.h"
+#include "DrawingModeAlphaCCSUBPIX.h"
+#include "DrawingModeAlphaCOSUBPIX.h"
+#include "DrawingModeAlphaCOSolidSUBPIX.h"
+#include "DrawingModeAlphaPCSUBPIX.h"
+#include "DrawingModeAlphaPOSUBPIX.h"
+#include "DrawingModeAlphaPOSolidSUBPIX.h"
+#include "DrawingModeBlendSUBPIX.h"
+#include "DrawingModeCopySUBPIX.h"
+#include "DrawingModeCopySolidSUBPIX.h"
+#include "DrawingModeCopyTextSUBPIX.h"
+#include "DrawingModeEraseSUBPIX.h"
+#include "DrawingModeInvertSUBPIX.h"
+#include "DrawingModeMinSUBPIX.h"
+#include "DrawingModeMaxSUBPIX.h"
+#include "DrawingModeOverSUBPIX.h"
+#include "DrawingModeOverSolidSUBPIX.h"
+#include "DrawingModeSelectSUBPIX.h"
+#include "DrawingModeSubtractSUBPIX.h"
+
 #include "PatternHandler.h"
 
 // blend_pixel_empty
@@ -53,6 +74,15 @@
        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,
@@ -71,6 +101,15 @@
        printf("blend_solid_hspan_empty()\n");
 }
 
+// blend_solid_hspan_subpix_empty
+void
+blend_solid_hspan_empty_subpix(int x, int y, unsigned len,
+                                               const color_type& c, const 
uint8* covers,
+                                               agg_buffer* buffer, const 
PatternHandler* pattern)
+{
+       printf("blend_solid_hspan_empty_subpix()\n");
+}
+
 // blend_solid_vspan_empty
 void
 blend_solid_vspan_empty(int x, int y,
@@ -112,8 +151,10 @@
 
          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),
          fBlendSolidVSpan(blend_solid_vspan_empty),
          fBlendColorHSpan(blend_color_hspan_empty),
          fBlendColorVSpan(blend_color_vspan_empty)
@@ -140,9 +181,13 @@
                                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;
                        }
@@ -151,6 +196,8 @@
                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;
                        fBlendColorHSpan = blend_color_hspan_erase;
@@ -158,6 +205,8 @@
                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;
                        fBlendColorHSpan = blend_color_hspan_invert;
@@ -165,6 +214,8 @@
                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;
                        fBlendColorHSpan = blend_color_hspan_select;
@@ -175,7 +226,9 @@
                case B_OP_COPY:
                        if (text) {
                                fBlendPixel = blend_pixel_copy_text;
-                               fBlendHLine = blend_hline_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;
                                fBlendColorHSpan = blend_color_hspan_copy_text;
@@ -186,12 +239,16 @@
                        } 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;
                                fBlendColorHSpan = blend_color_hspan_copy_solid;
                        } 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;
                                fBlendColorHSpan = blend_color_hspan_copy;
@@ -199,7 +256,9 @@
                        break;
                case B_OP_ADD:
                        fBlendPixel = blend_pixel_add;
-                       fBlendHLine = blend_hline_add;
+                       fBlendHLine = blend_hline_add;                  
+                       fBlendHLineSubpix = blend_hline_add_subpix;
+                       fBlendSolidHSpanSubpix = blend_solid_hspan_add_subpix;
                        fBlendSolidHSpan = blend_solid_hspan_add;
                        fBlendSolidVSpan = blend_solid_vspan_add;
                        fBlendColorHSpan = blend_color_hspan_add;
@@ -207,6 +266,8 @@
                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;
                        fBlendColorHSpan = blend_color_hspan_subtract;
@@ -214,6 +275,8 @@
                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;
                        fBlendColorHSpan = blend_color_hspan_blend;
@@ -221,6 +284,8 @@
                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;
                        fBlendColorHSpan = blend_color_hspan_min;
@@ -228,6 +293,8 @@
                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;
                        fBlendColorHSpan = blend_color_hspan_max;
@@ -247,11 +314,15 @@
                                        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;
                                        }
@@ -259,6 +330,8 @@
                                } 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;
                                        fBlendColorHSpan = 
blend_color_hspan_alpha_cc;
@@ -268,11 +341,15 @@
                                        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;
                                        }
@@ -280,6 +357,8 @@
                                } 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;
                                        fBlendColorHSpan = 
blend_color_hspan_alpha_pc;
Index: src/servers/app/drawing/Painter/drawing_modes/DrawingModeCopySUBPIX.h
===================================================================
--- src/servers/app/drawing/Painter/drawing_modes/DrawingModeCopySUBPIX.h       
(revision 0)
+++ src/servers/app/drawing/Painter/drawing_modes/DrawingModeCopySUBPIX.h       
(revision 0)
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2005, Stephan Aßmus <superstippi@xxxxxx>.
+ * Copyright 2008, Andrej Spielmann <andrej.spielmann@xxxxxxxxxxxx>.
+ * All rights reserved. Distributed under the terms of the MIT License.
+ *
+ * DrawingMode implementing B_OP_COPY on B_RGBA32.
+ *
+ */
+
+#ifndef DRAWING_MODE_COPY_SUBPIX_H
+#define DRAWING_MODE_COPY_SUBPIX_H
+
+#include "DrawingMode.h"
+
+// BLEND_COPY_SUBPIX
+#define BLEND_COPY_SUBPIX(d, r2, g2, b2, a1, a2, a3, r1, g1, b1) \
+{ \
+       BLEND_FROM_SUBPIX(d, r1, g1, b1, r2, g2, b2, a1, a2, a3); \
+}
+
+// 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, const uint8* covers,
+                                 agg_buffer* buffer, const PatternHandler* 
pattern)
+{
+       uint8* p = buffer->row_ptr(y) + (x << 2);
+       rgb_color l = pattern->LowColor();
+       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 += 3;
+               p += 4;
+               x++;
+               if (len>3) len -= 3; else len = 0;
+       } while(len);
+}
+
+#endif // DRAWING_MODE_COPY_SUBPIX_H
+
Index: src/servers/app/drawing/Painter/Painter.cpp
===================================================================
--- src/servers/app/drawing/Painter/Painter.cpp (revision 26239)
+++ src/servers/app/drawing/Painter/Painter.cpp (working copy)
@@ -1,6 +1,7 @@
 /*
- * Copyright 2005-2007, Stephan Aßmus <superstippi@xxxxxx>. All rights 
reserved.
- * Distributed under the terms of the MIT License.
+ * Copyright 2005-2007, Stephan Aßmus <superstippi@xxxxxx>.
+ * Copyright 2008, Andrej Spielmann <andrej.spielmann@xxxxxxxxxxxx>.
+ * All rights reserved. Distributed under the terms of the MIT License.
  *
  * API to the Anti-Grain Geometry based "Painter" drawing backend. Manages
  * rendering pipe-lines for stroke, fills, bitmap and text rendering.
@@ -57,6 +58,7 @@
          fUnpackedScanline(),
          fPackedScanline(),
          fRasterizer(),
+         fSubpixRenderer(fBaseRenderer),
          fRenderer(fBaseRenderer),
          fRendererBin(fBaseRenderer),
 
@@ -67,6 +69,7 @@
          fValidClipping(false),
          fDrawingText(false),
          fAttached(false),
+         fSubpixelAntialias(true),
 
          fPenSize(1.0),
          fClippingRegion(NULL),
@@ -78,7 +81,7 @@
          fMiterLimit(B_DEFAULT_MITER_LIMIT),
 
          fPatternHandler(),
-         fTextRenderer(fRenderer, fRendererBin, fUnpackedScanline)
+         fTextRenderer(fSubpixRenderer, fRenderer, fRendererBin, 
fUnpackedScanline)
 {
        fPixelFormat.SetDrawingMode(fDrawingMode, fAlphaSrcMode, fAlphaFncMode, 
false);
 
@@ -223,6 +226,14 @@
        }
 }
 
+void
+Painter::SetSubpixelAntialiasing(bool subpixelAntialias)
+{
+       if (fSubpixelAntialias != subpixelAntialias) {
+               fSubpixelAntialias = subpixelAntialias;
+       }
+}
+
 // SetBlendingMode
 void
 Painter::SetBlendingMode(source_alpha srcAlpha, alpha_function alphaFunc)
@@ -1172,6 +1183,10 @@
                                                          color.green / 255.0,
                                                          color.blue / 255.0,
                                                          color.alpha / 255.0));
+       fSubpixRenderer.color(agg::rgba(color.red / 255.0,
+                                                         color.green / 255.0,
+                                                         color.blue / 255.0,
+                                                         color.alpha / 255.0));
 // TODO: bitmap fonts not yet correctly setup in AGGTextRenderer
 //     fRendererBin.color(agg::rgba(color.red / 255.0,
 //                                                              color.green / 
255.0,
Index: src/servers/app/drawing/Painter/defines.h
===================================================================
--- src/servers/app/drawing/Painter/defines.h   (revision 26239)
+++ src/servers/app/drawing/Painter/defines.h   (working copy)
@@ -1,6 +1,7 @@
 /*
- * Copyright 2005-2006, Stephan Aßmus <superstippi@xxxxxx>. All rights 
reserved.
- * Distributed under the terms of the MIT License.
+ * Copyright 2005-2006, Stephan Aßmus <superstippi@xxxxxx>.
+ * Copyright 2008, Andrej Spielmann <andrej.spielmann@xxxxxxxxxxxx>.
+ * All rights reserved. Distributed under the terms of the MIT License.
  *
  * global definitions for the Painter frame work, mainly types for the
  * AGG pipelines
@@ -22,6 +23,7 @@
 #include <agg_rendering_buffer.h>
 
 #include "agg_renderer_region.h"
+#include "agg_renderer_scanline_subpix.h"
 
 #include "PixelFormat.h"
 
@@ -47,6 +49,7 @@
 #endif
 
        typedef agg::renderer_scanline_bin_solid<renderer_base>         
renderer_bin_type;
+       typedef agg::renderer_scanline_subpix_solid<renderer_base>  
renderer_subpix_type;
 
        typedef agg::rasterizer_scanline_aa<>                                   
        rasterizer_type;
 
Index: src/servers/app/drawing/Painter/Painter.h
===================================================================
--- src/servers/app/drawing/Painter/Painter.h   (revision 26239)
+++ src/servers/app/drawing/Painter/Painter.h   (working copy)
@@ -1,6 +1,7 @@
 /*
- * Copyright 2005-2007, Stephan Aßmus <superstippi@xxxxxx>. All rights 
reserved.
- * Distributed under the terms of the MIT License.
+ * Copyright 2005-2007, Stephan Aßmus <superstippi@xxxxxx>.
+ * Copyright 2008, Andrej Spielmann <andrej.spielmann@xxxxxxxxxxxx>.
+ * All rights reserved. Distributed under the terms of the MIT License.
  *
  * API to the Anti-Grain Geometry based "Painter" drawing backend. Manages
  * rendering pipe-lines for stroke, fills, bitmap and text rendering.
@@ -72,6 +73,9 @@
                        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);
 
@@ -261,6 +265,7 @@
 mutable scanline_unpacked_type fUnpackedScanline;
 mutable scanline_packed_type   fPackedScanline;
 mutable rasterizer_type                        fRasterizer;
+mutable renderer_subpix_type   fSubpixRenderer;
 mutable renderer_type                  fRenderer;
 mutable renderer_bin_type              fRendererBin;
 
@@ -281,6 +286,7 @@
        cap_mode                                        fLineCapMode;
        join_mode                                       fLineJoinMode;
        float                                           fMiterLimit;
+       bool                                            fSubpixelAntialias;
 
        PatternHandler                          fPatternHandler;
 
Index: src/servers/app/drawing/Painter/AGGTextRenderer.cpp
===================================================================
--- src/servers/app/drawing/Painter/AGGTextRenderer.cpp (revision 26239)
+++ src/servers/app/drawing/Painter/AGGTextRenderer.cpp (working copy)
@@ -1,6 +1,7 @@
 /*
- * Copyright 2005-2007, Stephan Aßmus <superstippi@xxxxxx>. All rights 
reserved.
- * Distributed under the terms of the MIT License.
+ * Copyright 2005-2007, Stephan Aßmus <superstippi@xxxxxx>.
+ * Copyright 2008, Andrej Spielmann <andrej.spielmann@xxxxxxxxxxxx>.
+ * All rights reserved. Distributed under the terms of the MIT License.
  */
 
 
@@ -29,19 +30,22 @@
 
 
 // constructor
-AGGTextRenderer::AGGTextRenderer(renderer_type& solidRenderer,
-               renderer_bin_type& binRenderer, scanline_unpacked_type& 
scanline)
+AGGTextRenderer::AGGTextRenderer(renderer_subpix_type& subpixRenderer,
+               renderer_type& solidRenderer, renderer_bin_type& binRenderer,
+               scanline_unpacked_type& scanline)
        : fPathAdaptor()
        , fGray8Adaptor()
        , fGray8Scanline()
        , fMonoAdaptor()
        , fMonoScanline()
+       , fSubpixAdaptor()
 
        , fCurves(fPathAdaptor)
        , fContour(fCurves)
 
        , fSolidRenderer(solidRenderer)
        , fBinRenderer(binRenderer)
+       , fSubpixRenderer(subpixRenderer)
        , fScanline(scanline)
        , fRasterizer()
 
@@ -218,6 +222,12 @@
                                                
agg::render_scanlines(fRenderer.fGray8Adaptor, 
                                                        
fRenderer.fGray8Scanline, fRenderer.fSolidRenderer);
                                                break;
+                                               
+                                       case glyph_data_subpix:
+                                               
agg::render_scanlines(fRenderer.fGray8Adaptor,
+                                                       
fRenderer.fGray8Scanline,
+                                                       
fRenderer.fSubpixRenderer);
+                                               break;
 
                                        case glyph_data_outline: {
                                                fVector = true;
Index: src/servers/app/drawing/Painter/agg_renderer_region.h
===================================================================
--- src/servers/app/drawing/Painter/agg_renderer_region.h       (revision 26239)
+++ src/servers/app/drawing/Painter/agg_renderer_region.h       (working copy)
@@ -1,5 +1,6 @@
 /*
  * Copyright 2005-2006, Stephan Aßmus <superstippi@xxxxxx>.
+ * Copyright 2008, Andrej Spielmann <andrej.spielmann@xxxxxxxxxxxx>.
  * All rights reserved. Distributed under the terms of the MIT License.
  *
  * Copyright 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
@@ -200,6 +201,18 @@
             }
             while(next_clip_box());
         }
+               
+               
//--------------------------------------------------------------------
+        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, 
@@ -248,6 +261,18 @@
             }
             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, 
Index: src/servers/app/Desktop.h
===================================================================
--- src/servers/app/Desktop.h   (revision 26239)
+++ src/servers/app/Desktop.h   (working copy)
@@ -6,6 +6,7 @@
  *             Adrian Oanca <adioanca@xxxxxxxxxxxxx>
  *             Stephan Aßmus <superstippi@xxxxxx>
  *             Axel Dörfler, axeld@xxxxxxxxxxxxxxxx
+ *             Andrej Spielmann, <andrej.spielmann@xxxxxxxxxxxx>
  */
 #ifndef DESKTOP_H
 #define DESKTOP_H
@@ -190,6 +191,7 @@
 #endif // USE_MULTI_LOCKER
 
                void                                    MarkDirty(BRegion& 
region);
+               void                                    Redraw();
 
                BRegion&                                BackgroundRegion()
                                                                        { 
return fBackgroundRegion; }
Index: src/servers/app/DesktopSettings.cpp
===================================================================
--- src/servers/app/DesktopSettings.cpp (revision 26239)
+++ src/servers/app/DesktopSettings.cpp (working copy)
@@ -5,12 +5,15 @@
  * Authors:
  *             Stephan Aßmus <superstippi@xxxxxx>
  *             Axel Dörfler, axeld@xxxxxxxxxxxxxxxx
+ *             Andrej Spielmann, <andrej.spielmann@xxxxxxxxxxxx>
  */
 
 
 #include "DesktopSettings.h"
 #include "DesktopSettingsPrivate.h"
 #include "Desktop.h"
+#include "FontCache.h"
+#include "FontCacheEntry.h"
 #include "FontManager.h"
 #include "ServerConfig.h"
 
@@ -69,6 +72,11 @@
        fWorkspacesCount = 4;
 
        memcpy(fShared.colors, BPrivate::kDefaultColors, sizeof(rgb_color) * 
kNumColors);
+       
+       fFontSubpixelAntialiasing = false;
+       FontCacheEntry::SetDefaultRenderType(glyph_ren_native_gray8);
+       fHinting = true;
+       FontCacheEntry::SetDefaultHinting(true);
 }
 
 
@@ -136,6 +144,8 @@
                        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
                                && settings.FindFloat("plain size", &size) == 
B_OK) {
@@ -158,7 +168,16 @@
                                        fFixedFont.SetStyle(fontStyle);
                                fFixedFont.SetSize(size);
                        }
-                       gFontManager->Unlock();
+                       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);
+                       }
+                       gFontManager->Unlock();                 
                }
        }
 
@@ -273,6 +292,9 @@
                        settings.AddString("fixed family", fFixedFont.Family());
                        settings.AddString("fixed style", fFixedFont.Style());
                        settings.AddFloat("fixed size", fFixedFont.Size());
+                       
+                       settings.AddBool("font 
subpix",fFontSubpixelAntialiasing);
+                       settings.AddBool("hinting",fHinting);
 
                        BFile file;
                        status = file.SetTo(path.Path(), B_CREATE_FILE | 
B_ERASE_FILE | B_READ_WRITE);
@@ -520,7 +542,39 @@
        return fShared.colors[index];
 }
 
+void
+DesktopSettingsPrivate::SetFontSubpixelAntialiasing(bool subpix)
+{
+       if (fFontSubpixelAntialiasing != subpix) {
+               fFontSubpixelAntialiasing = subpix;
+               FontCacheEntry::SetDefaultRenderType(
+                       (subpix)?glyph_ren_subpix:glyph_ren_native_gray8);
+               Save(kFontSettings);
+       }
+}
 
+bool
+DesktopSettingsPrivate::FontSubpixelAntialiasing() const
+{
+       return fFontSubpixelAntialiasing;
+}
+
+void
+DesktopSettingsPrivate::SetHinting(bool hinting)
+{
+       if (fHinting != hinting) {
+               fHinting = hinting;
+               FontCacheEntry::SetDefaultHinting(hinting);
+               Save(kFontSettings);
+       }
+}
+
+bool
+DesktopSettingsPrivate::Hinting() const
+{
+       return fHinting;
+}
+
 //     #pragma mark - read access
 
 
@@ -612,7 +666,18 @@
        return fSettings->UIColor(which);
 }
 
+bool
+DesktopSettings::FontSubpixelAntialiasing() const
+{
+       return fSettings->FontSubpixelAntialiasing();
+}
 
+bool
+DesktopSettings::Hinting() const
+{
+       return fSettings->Hinting();
+}
+
 //     #pragma mark - write access
 
 
@@ -690,4 +755,16 @@
        fSettings->SetUIColor(which, color);
 }
 
+void
+LockedDesktopSettings::SetFontSubpixelAntialiasing(bool subpix)
+{
+       fSettings->SetFontSubpixelAntialiasing(subpix);
+}
 
+void
+LockedDesktopSettings::SetHinting(bool hinting)
+{
+       fSettings->SetHinting(hinting);
+}
+
+
Index: src/servers/app/ProfileMessageSupport.cpp
===================================================================
--- src/servers/app/ProfileMessageSupport.cpp   (revision 26239)
+++ src/servers/app/ProfileMessageSupport.cpp   (working copy)
@@ -9,7 +9,7 @@
 
 #include "ProfileMessageSupport.h"
 
-#include "ServerProtocol.h"
+#include <ServerProtocol.h>
 
 
 void
@@ -174,6 +174,11 @@
                case AS_GET_DECORATOR_SETTINGS: string = 
"AS_GET_DECORATOR_SETTINGS"; break;
                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;
+               case AS_SET_HINTING: string = "AS_SET_HINTING"; break;
+               case AS_GET_HINTING: string = "AS_GET_HINTING"; break;
 
                // Graphics calls
                case AS_SET_HIGH_COLOR: string = "AS_SET_HIGH_COLOR"; break;
Index: src/servers/app/Desktop.cpp
===================================================================
--- src/servers/app/Desktop.cpp (revision 26239)
+++ src/servers/app/Desktop.cpp (working copy)
@@ -6,6 +6,7 @@
  *             Adrian Oanca <adioanca@xxxxxxxxxxxxx>
  *             Stephan Aßmus <superstippi@xxxxxx>
  *             Axel Dörfler, axeld@xxxxxxxxxxxxxxxx
+ *             Andrej Spielmann, <andrej.spielmann@xxxxxxxxxxxx>
  */
 
 /*!    Class used to encapsulate desktop management */
@@ -2462,6 +2463,14 @@
 
 
 void
+Desktop::Redraw()
+{
+       BRegion dirty(fVirtualScreen.Frame());
+       MarkDirty(dirty);
+}
+
+
+void
 Desktop::_RebuildClippingForAllWindows(BRegion& stillAvailableOnScreen)
 {
        // the available region on screen starts with the entire screen area
Index: src/servers/app/DesktopSettingsPrivate.h
===================================================================
--- src/servers/app/DesktopSettingsPrivate.h    (revision 26239)
+++ src/servers/app/DesktopSettingsPrivate.h    (working copy)
@@ -4,6 +4,7 @@
  *
  * Authors:
  *             Axel Dörfler, axeld@xxxxxxxxxxxxxxxx
+ *             Andrej Spielmann, <andrej.spielmann@xxxxxxxxxxxx>
  */
 #ifndef DESKTOP_SETTINGS_PRIVATE_H
 #define DESKTOP_SETTINGS_PRIVATE_H
@@ -54,6 +55,12 @@
 
                void                    SetUIColor(color_which which, const 
rgb_color color);
                rgb_color               UIColor(color_which which) const;
+               
+               void                    SetFontSubpixelAntialiasing(bool 
subpix);
+               bool                    FontSubpixelAntialiasing() const;
+               void                    SetHinting(bool hinting);
+               bool                    Hinting() const;
+               
        private:
                void                    _SetDefaults();
                status_t                _Load();
@@ -69,6 +76,9 @@
                bool                    fShowAllDraggers;
                int32                   fWorkspacesCount;
                BMessage                fWorkspaceMessages[kMaxWorkspaces];
+               
+               bool                    fFontSubpixelAntialiasing;
+               bool                    fHinting;
 
                server_read_only_memory& fShared;
 };
Index: src/servers/app/agg_scanline_u_subpix.h
===================================================================
--- src/servers/app/agg_scanline_u_subpix.h     (revision 0)
+++ src/servers/app/agg_scanline_u_subpix.h     (revision 0)
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2008, Andrej Spielmann <andrej.spielmann@xxxxxxxxxxxx>.
+ * All rights reserved. Distributed under the terms of the MIT License.
+ *
+ * Copyright 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
+ *
+ *
+ * Class scanline_u8_subpix, a slightly modified version of
+ * scanline_u8 customized to store 3 covers per pixel
+ *
+ */
+
+#ifndef AGG_SCANLINE_U_SUBPIX_INCLUDED
+#define AGG_SCANLINE_U_SUBPIX_INCLUDED
+
+#include <agg_array.h>
+
+namespace agg
+{
+    //======================================================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;
+        };
+
+        typedef span* iterator;
+        typedef const span* const_iterator;
+
+        //--------------------------------------------------------------------
+        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 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 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(const self_type&);
+        const self_type& operator = (const self_type&);
+
+    private:
+        int                   m_min_x;
+        int                   m_last_x;
+        int                   m_y;
+        pod_array<cover_type> m_covers;
+        pod_array<span>       m_spans;
+        span*                 m_cur_span;
+    };
+
+}
+
+#endif
+

Property changes on: src/servers/app/agg_scanline_u_subpix.h
___________________________________________________________________
Name: svn:executable
   + *

Other related posts: