Patch by Andrej Spielmann (GSoC):

* Simplified the subpixel related methods for the AGG "pixel format" template
  interface, the ones for the solid cover simply pass through the existing
  methods, so only one subpixel blending function is left which does the actual
  work (this removes a lot of the previously added code)
* Implemented a new rasterizer based on the original AGG rasterizer which
  implements subpixel anti-aliasing for any generic AGG vector pipelines. It
  is now optionally used in Painter and AGGTextRenderer (for vector fonts, ie
  rotated, sheared or big enough fonts) depending on the global subpixel
  setting.
* Put all subpixel variables into the new GlobalSubpixelSettings.h|cpp
* Simplified DesktopSettings related classes a bit and renamed previous
  FontSubpixelAntialiasing to just SubpixelAntialiasing.
* The private libbe functions for subpixel related settings moved from Font.cpp
  to InterfaceDefs.cpp where other such functions live. They are not related
  to fonts only anymore.
* Removed the subpixel related settings again from the Fonts preflet and added
  them to the Appearance preflet instead.

All of the above implements subpixel anti-aliasing on a global scale, which
to my knowledge no other OS is doing at the moment. Any vector rendering
can optionally use subpixel anti-aliasing in Haiku now. The bitmap cached fonts
are still affected by the Freetype complile time #define to enable the patented
subpixel rasterization (three times wide glyphs). Vector fonts and shapes are
not affected though at the moment.



git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26755 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus 2008-08-03 13:40:41 +00:00
parent 826df7bec8
commit 59e13a3f06
63 changed files with 3131 additions and 2555 deletions

View File

@ -206,21 +206,6 @@ namespace agg
m_ren->blend_hline(x1, y, x2 - x1 + 1, c, cover);
}
//--------------------------------------------------------------------
void blend_hline_subpix(int x1, int y, int x2,
const color_type& c, cover_type cover)
{
if(x1 > x2) { int t = x2; x2 = x1; x1 = t; }
if(y > ymax()) return;
if(y < ymin()) return;
if(x1 > xmax()) return;
if(x2 < xmin()) return;
if(x1 < xmin()) x1 = xmin();
if(x2 > xmax()) x2 = xmax();
m_ren->blend_hline_subpix(x1, y, x2 - x1 + 1, c, cover);
}
//--------------------------------------------------------------------
void blend_vline(int x, int y1, int y2,
@ -309,7 +294,7 @@ namespace agg
{
len -= 3 * (xmin() - x);
if(len <= 0) return;
covers += 3*(xmin() - x);
covers += 3 * (xmin() - x);
x = xmin();
}
if(x + len / 3 > xmax())

View File

@ -189,10 +189,15 @@ enum {
AS_GET_SHOW_ALL_DRAGGERS,
AS_SET_SHOW_ALL_DRAGGERS,
AS_SET_FONT_SUBPIXEL_ANTIALIASING,
AS_GET_FONT_SUBPIXEL_ANTIALIASING,
// Subpixel antialiasing & hinting
AS_SET_SUBPIXEL_ANTIALIASING,
AS_GET_SUBPIXEL_ANTIALIASING,
AS_SET_HINTING,
AS_GET_HINTING,
AS_SET_SUBPIXEL_AVERAGE_WEIGHT,
AS_GET_SUBPIXEL_AVERAGE_WEIGHT,
AS_SET_SUBPIXEL_ORDERING,
AS_GET_SUBPIXEL_ORDERING,
// Graphics calls
AS_SET_HIGH_COLOR,

View File

@ -406,59 +406,6 @@ _get_system_default_font_(const char* which, font_family family,
}
void
_set_font_subpixel_antialiasing_(bool subpix)
{
BPrivate::AppServerLink link;
link.StartMessage(AS_SET_FONT_SUBPIXEL_ANTIALIASING);
link.Attach<bool>(subpix);
link.Flush();
}
status_t
_get_font_subpixel_antialiasing_(bool* subpix)
{
BPrivate::AppServerLink link;
link.StartMessage(AS_GET_FONT_SUBPIXEL_ANTIALIASING);
int32 status = B_ERROR;
if (link.FlushWithReply(status) != B_OK
|| status < B_OK)
return status;
link.Read<bool>(subpix);
return B_OK;
}
void
_set_hinting_(bool hinting)
{
BPrivate::AppServerLink link;
link.StartMessage(AS_SET_HINTING);
link.Attach<bool>(hinting);
link.Flush();
}
status_t
_get_hinting_(bool* hinting)
{
BPrivate::AppServerLink link;
link.StartMessage(AS_GET_HINTING);
int32 status = B_ERROR;
if (link.FlushWithReply(status) != B_OK
|| status < B_OK)
return status;
link.Read<bool>(hinting);
return B_OK;
}
/*!
\brief Returns the number of installed font families
\return The number of installed font families

View File

@ -195,6 +195,107 @@ get_mode_parameter(uint32 mode, int32& width, int32& height, uint32& colorSpace)
} // namespace BPrivate
void
set_subpixel_antialiasing(bool subpix)
{
BPrivate::AppServerLink link;
link.StartMessage(AS_SET_SUBPIXEL_ANTIALIASING);
link.Attach<bool>(subpix);
link.Flush();
}
status_t
get_subpixel_antialiasing(bool* subpix)
{
BPrivate::AppServerLink link;
link.StartMessage(AS_GET_SUBPIXEL_ANTIALIASING);
int32 status = B_ERROR;
if (link.FlushWithReply(status) != B_OK || status < B_OK)
return status;
link.Read<bool>(subpix);
return B_OK;
}
void
set_hinting(bool hinting)
{
BPrivate::AppServerLink link;
link.StartMessage(AS_SET_HINTING);
link.Attach<bool>(hinting);
link.Flush();
}
status_t
get_hinting(bool* hinting)
{
BPrivate::AppServerLink link;
link.StartMessage(AS_GET_HINTING);
int32 status = B_ERROR;
if (link.FlushWithReply(status) != B_OK || status < B_OK)
return status;
link.Read<bool>(hinting);
return B_OK;
}
void
set_average_weight(uint8 averageWeight)
{
BPrivate::AppServerLink link;
link.StartMessage(AS_SET_SUBPIXEL_AVERAGE_WEIGHT);
link.Attach<uint8>(averageWeight);
link.Flush();
}
status_t
get_average_weight(uint8* averageWeight)
{
BPrivate::AppServerLink link;
link.StartMessage(AS_GET_SUBPIXEL_AVERAGE_WEIGHT);
int32 status = B_ERROR;
if (link.FlushWithReply(status) != B_OK || status < B_OK)
return status;
link.Read<uint8>(averageWeight);
return B_OK;
}
void
set_is_subpixel_ordering_regular(bool subpixelOrdering)
{
BPrivate::AppServerLink link;
link.StartMessage(AS_SET_SUBPIXEL_ORDERING);
link.Attach<bool>(subpixelOrdering);
link.Flush();
}
status_t
get_is_subpixel_ordering_regular(bool* subpixelOrdering)
{
BPrivate::AppServerLink link;
link.StartMessage(AS_GET_SUBPIXEL_ORDERING);
int32 status = B_ERROR;
if (link.FlushWithReply(status) != B_OK || status < B_OK)
return status;
link.Read<bool>(subpixelOrdering);
return B_OK;
}
const color_map *
system_colors()
{
@ -965,6 +1066,7 @@ set_decorator(const int32 &index)
return B_OK;
}
} // namespace BPrivate
// These methods were marked with "Danger, will Robinson!" in

View File

@ -18,6 +18,7 @@
#include <InterfaceDefs.h>
#include "APRView.h"
#include "APRWindow.h"
#include "defs.h"
#include "ColorWell.h"
#include "ColorWhichItem.h"
@ -152,26 +153,7 @@ APRView::APRView(const BRect &frame, const char *name, int32 resize, int32 flags
fPicker = new BColorControl(BPoint(fScrollView->Frame().left,fScrollView->Frame().bottom+kBorderSpace),B_CELLS_32x8,5.0,"fPicker",
new BMessage(UPDATE_COLOR));
AddChild(fPicker);
fDefaults = new BButton(BRect(0,0,1,1),"DefaultsButton","Defaults",
new BMessage(DEFAULT_SETTINGS),
B_FOLLOW_LEFT |B_FOLLOW_TOP, B_WILL_DRAW | B_NAVIGABLE);
fDefaults->ResizeToPreferred();
fDefaults->SetEnabled(false);
fDefaults->MoveTo(fPicker->Frame().left,fPicker->Frame().bottom+kBorderSpace);
AddChild(fDefaults);
BRect cvrect(fDefaults->Frame());
cvrect.OffsetBy(cvrect.Width() + kItemSpace,0);
fRevert = new BButton(cvrect,"RevertButton","Revert",
new BMessage(REVERT_SETTINGS),
B_FOLLOW_LEFT |B_FOLLOW_TOP, B_WILL_DRAW | B_NAVIGABLE);
fRevert->ResizeToPreferred();
fRevert->SetEnabled(false);
AddChild(fRevert);
AddChild(fPicker);
}
APRView::~APRView(void)
@ -184,21 +166,15 @@ APRView::AttachedToWindow(void)
{
fPicker->SetTarget(this);
fAttrList->SetTarget(this);
fDefaults->SetTarget(this);
fRevert->SetTarget(this);
fColorWell->SetTarget(this);
fPicker->SetValue(fCurrentSet.StringToColor(fAttrString.String()));
if (fDecorMenu)
fDecorMenu->SetTargetForItems(BMessenger(this));
Window()->ResizeTo(MAX(fPicker->Frame().right,fPicker->Frame().right) + 10,
fDefaults->Frame().bottom + 10);
LoadSettings();
fAttrList->Select(0);
fDefaults->SetEnabled(fCurrentSet.IsDefaultable());
}
void
@ -235,11 +211,9 @@ APRView::MessageReceived(BMessage *msg)
// Update current fAttribute in the settings
fCurrentSet.SetColor(fAttribute, col);
UpdateCurrentColor();
fDefaults->SetEnabled(fCurrentSet.IsDefaultable());
fRevert->SetEnabled(true);
UpdateCurrentColor();
Window()->PostMessage(kMsgUpdate);
break;
}
case ATTRIBUTE_CHOSEN: {
@ -254,7 +228,7 @@ APRView::MessageReceived(BMessage *msg)
fAttrString=whichitem->Text();
UpdateControlsFromAttr(whichitem->Text());
fDefaults->SetEnabled(fCurrentSet.IsDefaultable());
Window()->PostMessage(kMsgUpdate);
break;
}
case REVERT_SETTINGS: {
@ -262,13 +236,11 @@ APRView::MessageReceived(BMessage *msg)
UpdateControlsFromAttr(fAttrString.String());
UpdateAllColors();
fRevert->SetEnabled(false);
Window()->PostMessage(kMsgUpdate);
break;
}
case DEFAULT_SETTINGS: {
fCurrentSet = ColorSet::DefaultColorSet();
fDefaults->SetEnabled(false);
UpdateControlsFromAttr(fAttrString.String());
UpdateAllColors();
@ -281,6 +253,7 @@ APRView::MessageReceived(BMessage *msg)
BPrivate::set_decorator(fDecorMenu->IndexOf(item));
#endif
}
Window()->PostMessage(kMsgUpdate);
break;
}
default:
@ -302,6 +275,11 @@ void APRView::LoadSettings(void)
fPrevSet = fCurrentSet;
}
bool APRView::IsDefaultable(void)
{
return fCurrentSet.IsDefaultable();
}
void APRView::UpdateAllColors(void)
{
for (uint32 i = 0; i < sColorCount; i++)

View File

@ -40,6 +40,7 @@ public:
void MessageReceived(BMessage *msg);
void LoadSettings(void);
bool IsDefaultable(void);
protected:
@ -49,9 +50,6 @@ protected:
BColorControl *fPicker;
BButton *fRevert;
BButton *fDefaults;
BListView *fAttrList;
color_which fAttribute;

View File

@ -6,19 +6,101 @@
* DarkWyrm (darkwyrm@earthlink.net)
*/
#include <Button.h>
#include <Messenger.h>
#include <TabView.h>
#include "APRWindow.h"
#include "APRView.h"
#include "defs.h"
static const uint32 kMsgSetDefaults = 'dflt';
static const uint32 kMsgRevert = 'rvrt';
APRWindow::APRWindow(BRect frame)
: BWindow(frame, "Appearance", B_TITLED_WINDOW, B_NOT_RESIZABLE | B_NOT_ZOOMABLE,
B_ALL_WORKSPACES )
: BWindow(frame, "Appearance", B_TITLED_WINDOW, B_NOT_ZOOMABLE,
B_ALL_WORKSPACES)
{
APRView *colorview = new APRView(Bounds(),"Colors",B_FOLLOW_ALL, B_WILL_DRAW);
AddChild(colorview);
BRect rect = Bounds();
BView* view = new BView(rect, "background", B_FOLLOW_ALL, B_WILL_DRAW);
view->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
AddChild(view);
rect.left = 10;
rect.top = rect.bottom - 10;
fDefaultsButton = new BButton(rect, "defaults", "Defaults",
new BMessage(kMsgSetDefaults), B_FOLLOW_LEFT
| B_FOLLOW_BOTTOM, B_WILL_DRAW);
fDefaultsButton->ResizeToPreferred();
fDefaultsButton->SetEnabled(false);
float buttonHeight = fDefaultsButton->Bounds().Height();
fDefaultsButton->MoveBy(0, -buttonHeight);
view->AddChild(fDefaultsButton);
rect = fDefaultsButton->Frame();
rect.OffsetBy(fDefaultsButton->Bounds().Width() + 10, 0);
fRevertButton = new BButton(rect, "revert", "Revert",
new BMessage(kMsgRevert), B_FOLLOW_LEFT | B_FOLLOW_BOTTOM, B_WILL_DRAW);
fRevertButton->ResizeToPreferred();
fRevertButton->SetEnabled(false);
view->AddChild(fRevertButton);
rect = Bounds();
rect.top += 5;
rect.bottom -= 20 + buttonHeight;
rect.left += 5;
BTabView *tabView = new BTabView(rect, "tabview", B_WIDTH_FROM_LABEL);
rect = tabView->ContainerView()->Bounds().InsetByCopy(5, 8);
fAntialiasingSettings = new AntialiasingSettingsView(rect, "Antialiasing");
fColorsView = new APRView(rect,"Colors",B_FOLLOW_ALL, B_WILL_DRAW);
tabView->AddTab(fColorsView);
tabView->AddTab(fAntialiasingSettings);
view->AddChild(tabView);
fColorsView->ResizeToPreferred();
fAntialiasingSettings -> ResizeToPreferred();
fDefaultsButton -> SetEnabled(fColorsView -> IsDefaultable()
|| fAntialiasingSettings -> IsDefaultable());
fDefaultsButton -> SetTarget(this);
fRevertButton -> SetTarget(this);
}
void
APRWindow::MessageReceived(BMessage *message)
{
switch (message->what) {
case kMsgUpdate:
fDefaultsButton->SetEnabled(fColorsView->IsDefaultable()
|| fAntialiasingSettings->IsDefaultable());
fRevertButton->SetEnabled(true);
break;
case kMsgSetDefaults:
fColorsView -> MessageReceived(new BMessage(DEFAULT_SETTINGS));
fAntialiasingSettings->SetDefaults();
fDefaultsButton->SetEnabled(false);
fRevertButton->SetEnabled(true);
break;
case kMsgRevert:
fColorsView -> MessageReceived(new BMessage(REVERT_SETTINGS));
fAntialiasingSettings->Revert();
fDefaultsButton->SetEnabled(fColorsView->IsDefaultable()
|| fAntialiasingSettings->IsDefaultable());
fRevertButton->SetEnabled(false);
break;
default:
BWindow::MessageReceived(message);
break;
}
}
bool
APRWindow::QuitRequested(void)
{

View File

@ -9,14 +9,30 @@
#define APR_WINDOW_H
#include <Application.h>
#include <Button.h>
#include <Window.h>
#include <Message.h>
#include <TabView.h>
#include "APRView.h"
#include "AntialiasingSettingsView.h"
class APRWindow : public BWindow
{
public:
APRWindow(BRect frame);
bool QuitRequested(void);
void MessageReceived(BMessage *message);
private:
APRView* fColorsView;
BButton* fDefaultsButton;
BButton* fRevertButton;
AntialiasingSettingsView* fAntialiasingSettings;
};
static const int32 kMsgUpdate = 'updt';
#endif

View File

@ -1,59 +1,64 @@
/*
* Copyright 2008, Haiku. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Andrej Spielmann, <andrej.spielmann@seh.ox.ac.uk>
* Copyright 2008, Andrej Spielmann, <andrej.spielmann@seh.ox.ac.uk>
* All rights reserved. Distributed under the terms of the MIT License.
*/
#include "AntialiasingSettingsView.h"
#include "AdvancedSettingsView.h"
#include "MainWindow.h"
#include <stdio.h>
#include <stdlib.h>
#include <Box.h>
#include <MenuField.h>
#include <MenuItem.h>
#include <PopUpMenu.h>
#include <String.h>
#include <TextControl.h>
#include <stdio.h>
#include "APRWindow.h"
#define INSTANT_UPDATE
// if defined, the changes will take place immediately and not only on exit
#define DISABLE_HINTING_CONTROL
//#define DISABLE_HINTING_CONTROL
// if defined, the hinting menu is disabled (hinting not properly
// implemented)
static const int32 kMsgSetAntialiasing = 'anti';
static const int32 kMsgSetHinting = 'hint';
static const int32 kMsgSetAverageWeight = 'avrg';
static const char* kSubpixelLabel = "Subpixel antialiasing";
static const char* kGrayscaleLabel = "Grayscale antialiasing";
static const char* kNoHintingLabel = "Off";
static const char* kFullHintingLabel = "On";
// private font API
extern void _set_font_subpixel_antialiasing_(bool subpix);
extern status_t _get_font_subpixel_antialiasing_(bool* subpix);
extern void _set_hinting_(bool subpix);
extern status_t _get_hinting_(bool* subpix);
extern void set_subpixel_antialiasing(bool subpix);
extern status_t get_subpixel_antialiasing(bool* subpix);
extern void set_hinting(bool hinting);
extern status_t get_hinting(bool* hinting);
extern void set_average_weight(unsigned char averageWeight);
extern status_t get_average_weight(unsigned char* averageWeight);
// #pragma mark -
AdvancedSettingsView::AdvancedSettingsView(BRect _rect, const char* name)
AntialiasingSettingsView::AntialiasingSettingsView(BRect _rect, const char* name)
: BView(_rect, name, B_FOLLOW_LEFT_RIGHT, B_WILL_DRAW)
{
if (_get_font_subpixel_antialiasing_(&fCurrentSubpixelAntialiasing) != B_OK)
if (get_subpixel_antialiasing(&fCurrentSubpixelAntialiasing) != B_OK)
fCurrentSubpixelAntialiasing = false;
fSavedSubpixelAntialiasing = fCurrentSubpixelAntialiasing;
if (_get_hinting_(&fCurrentHinting) != B_OK)
if (get_hinting(&fCurrentHinting) != B_OK)
fCurrentHinting = true;
fSavedHinting = fCurrentHinting;
if (get_average_weight(&fCurrentAverageWeight) != B_OK)
fCurrentAverageWeight = 100;
fSavedAverageWeight = fCurrentAverageWeight;
fDivider = StringWidth("Character hinting:") + 5;
fDivider = StringWidth("Strength of colours in sbpx AA:") + 5;
fAntialiasingMenu = new BPopUpMenu("Antialiasing menu");
fHintingMenu = new BPopUpMenu("Hinting menu");
@ -68,8 +73,27 @@ AdvancedSettingsView::AdvancedSettingsView(BRect _rect, const char* name)
AddChild(fAntialiasingMenuField);
_BuildAntialiasingMenu();
// hinting menu
//Average weight in subpixel filtering
float shift = fAntialiasingMenuField->Bounds().Height()+5;
rect.top +=shift;
rect.bottom += shift;
fAverageWeightControl = new BTextControl(rect, "averageWeightControl",
"Strength of colours in sbpx AA:", NULL,
new BMessage(kMsgSetAverageWeight), B_FOLLOW_LEFT | B_FOLLOW_BOTTOM);
fAverageWeightControl -> SetDivider(fDivider);
fAverageWeightControl -> TextView() -> SetMaxBytes(3);
fAverageWeightControl -> ResizeToPreferred();
AddChild(fAverageWeightControl);
for (int i = 0; i < 256; i++) {
if (i < '0' || i > '9') {
fAverageWeightControl->TextView()->DisallowChar(i);
fAverageWeightControl->TextView()->DisallowChar(i);
}
}
fAverageWeightControl -> SetEnabled(false);
// hinting menu
shift = fAverageWeightControl->Bounds().Height()+5;
rect.top += shift;
rect.bottom += shift;
fHintingMenuField = new BMenuField(rect, "hinting",
@ -86,20 +110,22 @@ AdvancedSettingsView::AdvancedSettingsView(BRect _rect, const char* name)
_SetCurrentAntialiasing();
_SetCurrentHinting();
_SetCurrentAverageWeight();
}
AdvancedSettingsView::~AdvancedSettingsView()
AntialiasingSettingsView::~AntialiasingSettingsView()
{
#ifndef INSTANT_UPDATE
_set_font_subpixel_antialiasing_(fCurrentSubpixelAntialiasing);
_set_hinting(fCurrentHinting);
set_subpixel_antialiasing(fCurrentSubpixelAntialiasing);
set_hinting(fCurrentHinting);
set_average_weight(fCurrentAverageWeight);
#endif
}
void
AdvancedSettingsView::GetPreferredSize(float *_width, float *_height)
AntialiasingSettingsView::GetPreferredSize(float *_width, float *_height)
{
// don't change the width if it is large enough
if (_width) {
@ -115,16 +141,17 @@ AdvancedSettingsView::GetPreferredSize(float *_width, float *_height)
void
AdvancedSettingsView::SetDivider(float divider)
AntialiasingSettingsView::SetDivider(float divider)
{
fAntialiasingMenuField->SetDivider(divider);
fHintingMenuField->SetDivider(divider);
fAntialiasingMenuField -> SetDivider(divider);
fHintingMenuField -> SetDivider(divider);
fAverageWeightControl -> SetDivider(divider);
fDivider = divider;
}
void
AdvancedSettingsView::RelayoutIfNeeded()
AntialiasingSettingsView::RelayoutIfNeeded()
{
float width, height;
GetPreferredSize(&width, &height);
@ -136,19 +163,20 @@ AdvancedSettingsView::RelayoutIfNeeded()
void
AdvancedSettingsView::AttachedToWindow()
AntialiasingSettingsView::AttachedToWindow()
{
if (Parent() != NULL)
SetViewColor(Parent()->ViewColor());
else
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
fAntialiasingMenu->SetTargetForItems(this);
fHintingMenu->SetTargetForItems(this);
fAntialiasingMenu -> SetTargetForItems(this);
fHintingMenu -> SetTargetForItems(this);
fAverageWeightControl -> SetTarget(this);
}
void
AdvancedSettingsView::MessageReceived(BMessage *msg)
AntialiasingSettingsView::MessageReceived(BMessage *msg)
{
switch (msg->what) {
case kMsgSetAntialiasing:
@ -158,8 +186,9 @@ AdvancedSettingsView::MessageReceived(BMessage *msg)
|| subpixelAntialiasing == fCurrentSubpixelAntialiasing)
break;
fCurrentSubpixelAntialiasing = subpixelAntialiasing;
fAverageWeightControl -> SetEnabled(fCurrentSubpixelAntialiasing);
#ifdef INSTANT_UPDATE
_set_font_subpixel_antialiasing_(fCurrentSubpixelAntialiasing);
set_subpixel_antialiasing(fCurrentSubpixelAntialiasing);
#endif
Window()->PostMessage(kMsgUpdate);
break;
@ -172,7 +201,30 @@ AdvancedSettingsView::MessageReceived(BMessage *msg)
break;
fCurrentHinting = hinting;
#ifdef INSTANT_UPDATE
_set_hinting_(fCurrentHinting);
set_hinting(fCurrentHinting);
#endif
Window()->PostMessage(kMsgUpdate);
break;
}
case kMsgSetAverageWeight:
{
int subpixelWeight;
unsigned char averageWeight;
if (fAverageWeightControl -> Text() != NULL) {
subpixelWeight = atoi(fAverageWeightControl -> Text());
if (subpixelWeight > 255) {
subpixelWeight = 255;
BString subpixelWeightString;
subpixelWeightString << subpixelWeight;
fAverageWeightControl -> SetText(
subpixelWeightString.String());
}
averageWeight = 255 - subpixelWeight;
if (averageWeight == fCurrentAverageWeight) break;
} else break;
fCurrentAverageWeight = averageWeight;
#ifdef INSTANT_UPDATE
set_average_weight(fCurrentAverageWeight);
#endif
Window()->PostMessage(kMsgUpdate);
break;
@ -184,7 +236,7 @@ AdvancedSettingsView::MessageReceived(BMessage *msg)
void
AdvancedSettingsView::_BuildAntialiasingMenu()
AntialiasingSettingsView::_BuildAntialiasingMenu()
{
BMessage* message = new BMessage(kMsgSetAntialiasing);
message->AddBool("antialiasing", false);
@ -203,7 +255,7 @@ AdvancedSettingsView::_BuildAntialiasingMenu()
void
AdvancedSettingsView::_BuildHintingMenu()
AntialiasingSettingsView::_BuildHintingMenu()
{
BMessage* message = new BMessage(kMsgSetHinting);
message->AddBool("hinting", false);
@ -222,17 +274,18 @@ AdvancedSettingsView::_BuildHintingMenu()
void
AdvancedSettingsView::_SetCurrentAntialiasing()
AntialiasingSettingsView::_SetCurrentAntialiasing()
{
BMenuItem *item = fAntialiasingMenu->FindItem(
fCurrentSubpixelAntialiasing ? kSubpixelLabel : kGrayscaleLabel);
if (item != NULL)
item->SetMarked(true);
if (fCurrentSubpixelAntialiasing) fAverageWeightControl -> SetEnabled(true);
}
void
AdvancedSettingsView::_SetCurrentHinting()
AntialiasingSettingsView::_SetCurrentHinting()
{
BMenuItem *item = fHintingMenu->FindItem(
fCurrentHinting ? kFullHintingLabel : kNoHintingLabel);
@ -242,38 +295,51 @@ AdvancedSettingsView::_SetCurrentHinting()
void
AdvancedSettingsView::SetDefaults()
{
AntialiasingSettingsView::_SetCurrentAverageWeight()
{
BString subpixelWeightString;
subpixelWeightString << (255 - fCurrentAverageWeight);
fAverageWeightControl -> SetText(subpixelWeightString.String());
}
void
AntialiasingSettingsView::SetDefaults()
{
}
bool
AdvancedSettingsView::IsDefaultable()
AntialiasingSettingsView::IsDefaultable()
{
return false;
}
bool
AdvancedSettingsView::IsRevertable()
AntialiasingSettingsView::IsRevertable()
{
return (fCurrentSubpixelAntialiasing != fSavedSubpixelAntialiasing)
|| (fCurrentHinting != fSavedHinting);
|| (fCurrentHinting != fSavedHinting)
|| (fCurrentAverageWeight != fSavedAverageWeight);
}
void
AdvancedSettingsView::Revert()
AntialiasingSettingsView::Revert()
{
if (!IsRevertable())
return;
fCurrentSubpixelAntialiasing = fSavedSubpixelAntialiasing;
fCurrentHinting = fSavedHinting;
fCurrentAverageWeight = fSavedAverageWeight;
#ifdef INSTANT_UPDATE
_set_font_subpixel_antialiasing_(fCurrentSubpixelAntialiasing);
_set_hinting_(fCurrentHinting);
set_subpixel_antialiasing(fCurrentSubpixelAntialiasing);
set_hinting(fCurrentHinting);
set_average_weight(fCurrentAverageWeight);
#endif
_SetCurrentAntialiasing();
_SetCurrentHinting();
_SetCurrentAverageWeight();
}

View File

@ -0,0 +1,59 @@
/*
* Copyright 2008, Andrej Spielmann, <andrej.spielmann@seh.ox.ac.uk>
* All rights reserved. Distributed under the terms of the MIT License.
*/
#ifndef ANTIALIASING_SETTINGS_VIEW_H
#define ANTIALIASING_SETTINGS_VIEW_H
#include <View.h>
class BBox;
class BMenuField;
class BPopUpMenu;
class BTextControl;
class AntialiasingSettingsView : public BView {
public:
AntialiasingSettingsView(BRect rect,
const char* name);
virtual ~AntialiasingSettingsView();
virtual void GetPreferredSize(float *_width, float *_height);
virtual void RelayoutIfNeeded();
virtual void AttachedToWindow();
virtual void MessageReceived(BMessage *msg);
void SetDivider(float divider);
void SetDefaults();
void Revert();
bool IsDefaultable();
bool IsRevertable();
private:
void _BuildAntialiasingMenu();
void _SetCurrentAntialiasing();
void _BuildHintingMenu();
void _SetCurrentHinting();
void _SetCurrentAverageWeight();
protected:
float fDivider;
BMenuField* fAntialiasingMenuField;
BPopUpMenu* fAntialiasingMenu;
BMenuField* fHintingMenuField;
BPopUpMenu* fHintingMenu;
BTextControl* fAverageWeightControl;
bool fSavedSubpixelAntialiasing;
bool fCurrentSubpixelAntialiasing;
bool fSavedHinting;
bool fCurrentHinting;
unsigned char fSavedAverageWeight;
unsigned char fCurrentAverageWeight;
};
#endif // ANTIALIASING_SETTINGS_VIEW_H

View File

@ -5,6 +5,7 @@ UsePrivateHeaders app [ FDirName servers app ] ;
Preference Appearance :
APRMain.cpp
AntialiasingSettingsView.cpp
APRView.cpp
APRWindow.cpp
ColorSet.cpp

View File

@ -1,56 +0,0 @@
/*
* Copyright 2001-2005, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Andrej Spielmann, <andrej.spielmann@seh.ox.ac.uk>
*/
#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 */

View File

@ -12,7 +12,6 @@
#include "FontSelectionView.h"
#include "AdvancedSettingsView.h"
class FontView : public BView {

View File

@ -5,7 +5,6 @@ AddSubDirSupportedPlatforms libbe_test ;
Preference Fonts :
FontSelectionView.cpp
AdvancedSettingsView.cpp
FontsSettings.cpp
FontView.cpp
main.cpp

View File

@ -63,8 +63,6 @@ MainWindow::MainWindow()
rect = tabView->ContainerView()->Bounds().InsetByCopy(5, 8);
fFontsView = new FontView(rect);
fAdvancedSettings = new AdvancedSettingsView(rect, "Advanced");
tabView->AddTab(fFontsView);
fFontsView->UpdateFonts();
@ -104,23 +102,6 @@ MainWindow::MainWindow()
_Center();
}
tabView->AddTab(fAdvancedSettings);
fAdvancedSettings->RelayoutIfNeeded();
fAdvancedSettings->GetPreferredSize(&width, &height);
widthDiff = width + 10 - tabView->ContainerView()->Bounds().Width();
if (widthDiff > 0) {
tabView->ResizeBy(widthDiff, 0);
tabView->ContainerView()->ResizeBy(widthDiff, 0);
}
heightDiff = height + 16 - tabView->ContainerView()->Bounds().Height();
if (heightDiff > 0) {
tabView->ResizeBy(0, heightDiff);
tabView->ContainerView()->ResizeBy(0, heightDiff);
}
fRunner = new BMessageRunner(this, new BMessage(kMsgCheckFonts), 3000000);
// every 3 seconds
@ -149,25 +130,19 @@ MainWindow::MessageReceived(BMessage *message)
{
switch (message->what) {
case kMsgUpdate:
fDefaultsButton->SetEnabled(fFontsView->IsDefaultable()
|| fAdvancedSettings->IsDefaultable());
fRevertButton->SetEnabled(fFontsView->IsRevertable()
|| fAdvancedSettings->IsRevertable());
fDefaultsButton->SetEnabled(fFontsView->IsDefaultable());
fRevertButton->SetEnabled(fFontsView->IsRevertable());
break;
case kMsgSetDefaults:
fFontsView->SetDefaults();
fAdvancedSettings->SetDefaults();
fDefaultsButton->SetEnabled(false);
fRevertButton->SetEnabled(fFontsView->IsRevertable()
|| fAdvancedSettings->IsRevertable());
fRevertButton->SetEnabled(fFontsView->IsRevertable());
break;
case kMsgRevert:
fFontsView->Revert();
fAdvancedSettings->Revert();
fDefaultsButton->SetEnabled(fFontsView->IsDefaultable()
|| fAdvancedSettings->IsDefaultable());
fDefaultsButton->SetEnabled(fFontsView->IsDefaultable());
fRevertButton->SetEnabled(false);
break;

View File

@ -12,7 +12,6 @@
#include "FontsSettings.h"
#include "AdvancedSettingsView.h"
#include <Window.h>
@ -38,7 +37,6 @@ class MainWindow : public BWindow {
BButton* fRevertButton;
FontsSettings fSettings;
AdvancedSettingsView* fAdvancedSettings;
};
static const int32 kMsgUpdate = 'updt';

View File

@ -15,6 +15,7 @@
#include "FontCache.h"
#include "FontCacheEntry.h"
#include "FontManager.h"
#include "GlobalSubpixelSettings.h"
#include "ServerConfig.h"
#include <DefaultColors.h>
@ -73,10 +74,10 @@ DesktopSettingsPrivate::_SetDefaults()
memcpy(fShared.colors, BPrivate::kDefaultColors, sizeof(rgb_color) * kNumColors);
fFontSubpixelAntialiasing = false;
FontCacheEntry::SetDefaultRenderType(glyph_ren_native_gray8);
fHinting = true;
FontCacheEntry::SetDefaultHinting(true);
gSubpixelAntialiasing = false;
gDefaultHinting = true;
gSubpixelAverageWeight = 120;
gSubpixelOrderingRGB = true;
}
@ -144,7 +145,6 @@ DesktopSettingsPrivate::_Load()
const char* family;
const char* style;
float size;
bool subpix;
bool hinting;
if (settings.FindString("plain family", &family) == B_OK
&& settings.FindString("plain style", &style) == B_OK
@ -168,14 +168,8 @@ DesktopSettingsPrivate::_Load()
fFixedFont.SetStyle(fontStyle);
fFixedFont.SetSize(size);
}
if (settings.FindBool("font subpix", &subpix) == B_OK) {
fFontSubpixelAntialiasing = subpix;
FontCacheEntry::SetDefaultRenderType(
(subpix) ? glyph_ren_subpix : glyph_ren_native_gray8);
}
if (settings.FindBool("hinting", &hinting) == B_OK) {
fHinting = hinting;
FontCacheEntry::SetDefaultHinting(fHinting);
gDefaultHinting = hinting;
}
gFontManager->Unlock();
}
@ -233,8 +227,26 @@ DesktopSettingsPrivate::_Load()
fMenuInfo.click_to_open = clickToOpen;
bool triggersAlwaysShown;
if (settings.FindBool("triggers always shown", &triggersAlwaysShown) == B_OK)
if (settings.FindBool("triggers always shown", &triggersAlwaysShown)
== B_OK) {
fMenuInfo.triggers_always_shown = triggersAlwaysShown;
}
bool subpix;
if (settings.FindBool("subpixel antialiasing", &subpix) == B_OK)
gSubpixelAntialiasing = subpix;
int8 averageWeight;
if (settings.FindInt8("subpixel average weight", &averageWeight)
== B_OK) {
gSubpixelAverageWeight = averageWeight;
}
bool subpixelOrdering;
if (settings.FindBool("subpixel ordering", &subpixelOrdering)
== B_OK) {
gSubpixelOrderingRGB = subpixelOrdering;
}
for (int32 i = 0; i < kNumColors; i++) {
char colorName[12];
@ -269,7 +281,8 @@ DesktopSettingsPrivate::Save(uint32 mask)
}
BFile file;
status = file.SetTo(path.Path(), B_CREATE_FILE | B_ERASE_FILE | B_READ_WRITE);
status = file.SetTo(path.Path(), B_CREATE_FILE | B_ERASE_FILE
| B_READ_WRITE);
if (status == B_OK) {
status = settings.Flatten(&file, NULL);
}
@ -293,11 +306,11 @@ DesktopSettingsPrivate::Save(uint32 mask)
settings.AddString("fixed style", fFixedFont.Style());
settings.AddFloat("fixed size", fFixedFont.Size());
settings.AddBool("font subpix",fFontSubpixelAntialiasing);
settings.AddBool("hinting",fHinting);
settings.AddBool("hinting", gDefaultHinting);
BFile file;
status = file.SetTo(path.Path(), B_CREATE_FILE | B_ERASE_FILE | B_READ_WRITE);
status = file.SetTo(path.Path(), B_CREATE_FILE | B_ERASE_FILE
| B_READ_WRITE);
if (status == B_OK) {
status = settings.Flatten(&file, NULL);
}
@ -311,7 +324,8 @@ DesktopSettingsPrivate::Save(uint32 mask)
settings.AddInt32("mode", (int32)fMouseMode);
BFile file;
status = file.SetTo(path.Path(), B_CREATE_FILE | B_ERASE_FILE | B_READ_WRITE);
status = file.SetTo(path.Path(), B_CREATE_FILE | B_ERASE_FILE
| B_READ_WRITE);
if (status == B_OK) {
status = settings.Flatten(&file, NULL);
}
@ -325,7 +339,8 @@ DesktopSettingsPrivate::Save(uint32 mask)
settings.AddBool("show", fShowAllDraggers);
BFile file;
status = file.SetTo(path.Path(), B_CREATE_FILE | B_ERASE_FILE | B_READ_WRITE);
status = file.SetTo(path.Path(), B_CREATE_FILE | B_ERASE_FILE
| B_READ_WRITE);
if (status == B_OK) {
status = settings.Flatten(&file, NULL);
}
@ -339,10 +354,16 @@ DesktopSettingsPrivate::Save(uint32 mask)
settings.AddFloat("font size", fMenuInfo.font_size);
settings.AddString("font family", fMenuInfo.f_family);
settings.AddString("font style", fMenuInfo.f_style);
settings.AddInt32("bg color", (const int32&)fMenuInfo.background_color);
settings.AddInt32("bg color",
(const int32&)fMenuInfo.background_color);
settings.AddInt32("separator", fMenuInfo.separator);
settings.AddBool("click to open", fMenuInfo.click_to_open);
settings.AddBool("triggers always shown", fMenuInfo.triggers_always_shown);
settings.AddBool("triggers always shown",
fMenuInfo.triggers_always_shown);
settings.AddBool("subpixel antialiasing", gSubpixelAntialiasing);
settings.AddInt8("subpixel average weight", gSubpixelAverageWeight);
settings.AddBool("subpixel ordering", gSubpixelOrderingRGB);
for (int32 i = 0; i < kNumColors; i++) {
char colorName[12];
@ -352,7 +373,8 @@ DesktopSettingsPrivate::Save(uint32 mask)
}
BFile file;
status = file.SetTo(path.Path(), B_CREATE_FILE | B_ERASE_FILE | B_READ_WRITE);
status = file.SetTo(path.Path(), B_CREATE_FILE | B_ERASE_FILE
| B_READ_WRITE);
if (status == B_OK) {
status = settings.Flatten(&file, NULL);
}
@ -544,39 +566,62 @@ DesktopSettingsPrivate::UIColor(color_which which) const
void
DesktopSettingsPrivate::SetFontSubpixelAntialiasing(bool subpix)
DesktopSettingsPrivate::SetSubpixelAntialiasing(bool subpix)
{
if (fFontSubpixelAntialiasing != subpix) {
fFontSubpixelAntialiasing = subpix;
FontCacheEntry::SetDefaultRenderType(
(subpix)?glyph_ren_subpix:glyph_ren_native_gray8);
Save(kFontSettings);
}
gSubpixelAntialiasing = subpix;
Save(kAppearanceSettings);
}
bool
DesktopSettingsPrivate::FontSubpixelAntialiasing() const
DesktopSettingsPrivate::SubpixelAntialiasing() const
{
return fFontSubpixelAntialiasing;
return gSubpixelAntialiasing;
}
void
DesktopSettingsPrivate::SetHinting(bool hinting)
{
if (fHinting != hinting) {
fHinting = hinting;
FontCacheEntry::SetDefaultHinting(hinting);
Save(kFontSettings);
}
gDefaultHinting = hinting;
Save(kFontSettings);
}
bool
DesktopSettingsPrivate::Hinting() const
{
return fHinting;
return gDefaultHinting;
}
void
DesktopSettingsPrivate::SetSubpixelAverageWeight(uint8 averageWeight)
{
gSubpixelAverageWeight = averageWeight;
Save(kAppearanceSettings);
}
uint8
DesktopSettingsPrivate::SubpixelAverageWeight() const
{
return gSubpixelAverageWeight;
}
void
DesktopSettingsPrivate::SetSubpixelOrderingRegular(bool subpixelOrdering)
{
gSubpixelOrderingRGB = subpixelOrdering;
Save(kAppearanceSettings);
}
bool
DesktopSettingsPrivate::IsSubpixelOrderingRegular() const
{
return gSubpixelOrderingRGB;
}
// #pragma mark - read access
@ -672,9 +717,9 @@ DesktopSettings::UIColor(color_which which) const
bool
DesktopSettings::FontSubpixelAntialiasing() const
DesktopSettings::SubpixelAntialiasing() const
{
return fSettings->FontSubpixelAntialiasing();
return fSettings->SubpixelAntialiasing();
}
@ -684,6 +729,21 @@ DesktopSettings::Hinting() const
return fSettings->Hinting();
}
uint8
DesktopSettings::SubpixelAverageWeight() const
{
return fSettings->SubpixelAverageWeight();
}
bool
DesktopSettings::IsSubpixelOrderingRegular() const
{
// True corresponds to RGB, false means BGR
return fSettings->IsSubpixelOrderingRegular();
}
// #pragma mark - write access
@ -763,9 +823,9 @@ LockedDesktopSettings::SetUIColor(color_which which, const rgb_color color)
void
LockedDesktopSettings::SetFontSubpixelAntialiasing(bool subpix)
LockedDesktopSettings::SetSubpixelAntialiasing(bool subpix)
{
fSettings->SetFontSubpixelAntialiasing(subpix);
fSettings->SetSubpixelAntialiasing(subpix);
}
@ -775,3 +835,16 @@ LockedDesktopSettings::SetHinting(bool hinting)
fSettings->SetHinting(hinting);
}
void
LockedDesktopSettings::SetSubpixelAverageWeight(uint8 averageWeight)
{
fSettings->SetSubpixelAverageWeight(averageWeight);
}
void
LockedDesktopSettings::SetSubpixelOrderingRegular(bool subpixelOrdering)
{
fSettings->SetSubpixelOrderingRegular(subpixelOrdering);
}

View File

@ -53,8 +53,10 @@ class DesktopSettings {
rgb_color UIColor(color_which which) const;
bool FontSubpixelAntialiasing() const;
bool SubpixelAntialiasing() const;
bool Hinting() const;
uint8 SubpixelAverageWeight() const;
bool IsSubpixelOrderingRegular() const;
protected:
DesktopSettingsPrivate* fSettings;
@ -78,8 +80,10 @@ class LockedDesktopSettings : public DesktopSettings {
void SetUIColor(color_which which, const rgb_color color);
void SetFontSubpixelAntialiasing(bool subpix);
void SetSubpixelAntialiasing(bool subpix);
void SetHinting(bool hinting);
void SetSubpixelAverageWeight(uint8 averageWeight);
void SetSubpixelOrderingRegular(bool subpixelOrdering);
private:
Desktop* fDesktop;

View File

@ -56,10 +56,14 @@ class DesktopSettingsPrivate {
void SetUIColor(color_which which, const rgb_color color);
rgb_color UIColor(color_which which) const;
void SetFontSubpixelAntialiasing(bool subpix);
bool FontSubpixelAntialiasing() const;
void SetSubpixelAntialiasing(bool subpix);
bool SubpixelAntialiasing() const;
void SetHinting(bool hinting);
bool Hinting() const;
void SetSubpixelAverageWeight(uint8 averageWeight);
uint8 SubpixelAverageWeight() const;
void SetSubpixelOrderingRegular(bool SubpixelOrdering);
bool IsSubpixelOrderingRegular() const;
private:
void _SetDefaults();
@ -77,9 +81,6 @@ class DesktopSettingsPrivate {
int32 fWorkspacesCount;
BMessage fWorkspaceMessages[kMaxWorkspaces];
bool fFontSubpixelAntialiasing;
bool fHinting;
server_read_only_memory& fShared;
};

View File

@ -33,16 +33,12 @@
#include "utf8_functions.h"
#include "GlobalSubpixelSettings.h"
BLocker
FontCacheEntry::sUsageUpdateLock("FontCacheEntry usage lock");
glyph_rendering
FontCacheEntry::sDefaultRenderType;
bool
FontCacheEntry::sDefaultHinting;
class FontCacheEntry::GlyphCachePool {
public:
enum block_size_e { block_size = 16384-16 };
@ -127,7 +123,7 @@ FontCacheEntry::Init(const ServerFont& font)
// TODO: encoding from font
FT_Encoding charMap = FT_ENCODING_NONE;
bool hinting = sDefaultHinting; // TODO: font.Hinting();
bool hinting = gDefaultHinting; // TODO: font.Hinting();
if (!fEngine.Init(font.Path(), 0, font.Size(), charMap,
renderingType, hinting)) {
@ -224,11 +220,12 @@ FontCacheEntry::GenerateSignature(char* signature, const ServerFont& font)
// TODO: read more of these from the font
FT_Encoding charMap = FT_ENCODING_NONE;
bool hinting = sDefaultHinting; // TODO: font.Hinting();
bool hinting = gDefaultHinting; // TODO: font.Hinting();
uint8 averageWeight = gSubpixelAverageWeight;
sprintf(signature, "%ld,%u,%d,%d,%.1f,%d",
sprintf(signature, "%ld,%u,%d,%d,%.1f,%d,%d",
font.GetFamilyAndStyle(), charMap,
font.Face(), int(renderingType), font.Size(), hinting);
font.Face(), int(renderingType), font.Size(), hinting, averageWeight);
}
// UpdateUsage
@ -247,31 +244,20 @@ FontCacheEntry::UpdateUsage()
}
void
FontCacheEntry::SetDefaultRenderType(glyph_rendering renderingType)
{
sDefaultRenderType = renderingType;
}
void
FontCacheEntry::SetDefaultHinting(bool hinting)
{
sDefaultHinting = hinting;
}
// _RenderTypeFor
/*static*/ glyph_rendering
FontCacheEntry::_RenderTypeFor(const ServerFont& font)
{
glyph_rendering renderingType = sDefaultRenderType;
glyph_rendering renderingType = gSubpixelAntialiasing ?
glyph_ren_subpix : glyph_ren_native_gray8;
if (font.Rotation() != 0.0 || font.Shear() != 90.0
|| font.FalseBoldWidth() != 0.0
|| font.Flags() & B_DISABLE_ANTIALIASING
|| font.Size() > 30
|| !sDefaultHinting) {
|| !gDefaultHinting) {
renderingType = glyph_ren_outline;
}
return renderingType;
}

View File

@ -94,13 +94,6 @@ class FontCacheEntry : public MultiLocker, public Referenceable {
static void GenerateSignature(char* signature,
const ServerFont& font);
static void SetDefaultRenderType(glyph_rendering renderType);
static glyph_rendering DefaultRenderType()
{ return sDefaultRenderType; }
static void SetDefaultHinting(bool hinting);
static bool DefaultHinting()
{ return sDefaultHinting; }
// private to FontCache class:
void UpdateUsage();
@ -119,8 +112,6 @@ class FontCacheEntry : public MultiLocker, public Referenceable {
GlyphCachePool* fGlyphCache;
FontEngine fEngine;
static glyph_rendering sDefaultRenderType;
static bool sDefaultHinting;
static BLocker sUsageUpdateLock;
bigtime_t fLastUsedTime;

View File

@ -36,7 +36,7 @@
#include <agg_bitset_iterator.h>
#include <agg_renderer_scanline.h>
#include "GlobalSubpixelSettings.h"
static const bool kFlipY = true;
@ -365,21 +365,6 @@ decompose_ft_bitmap_gray8(const FT_Bitmap& bitmap, int x, int y,
}
#define AVERAGE_BASED_SUBPIXEL_FILTERING
// NOTE stippi: My basic idea is that filtering tries to minimize colored
// edges, but it does so by blurring the coverage values. This will also
// affect neighboring pixels and add blur where there were perfectly sharp
// edges. Andrej's method of filtering adds a special case for perfectly
// sharp edges, but the drawback here is that there will be a visible
// transition between blurred and non-blurred subpixels. I had the idea that
// when simply fading the subpixels towards the plain gray-scale-aa values,
// there must be a sweet spot for when colored edges become non-disturbing
// and there is still a benefit of sharpness compared to straight gray-scale-
// aa. The define above enables this method against the colored edges. My
// method still has a drawback, since jaggies in diagonal lines will be more
// visible again than with the filter method.
// decompose_ft_bitmap_subpix
template<class Scanline, class ScanlineStorage>
void
@ -387,13 +372,6 @@ decompose_ft_bitmap_subpix(const FT_Bitmap& bitmap, int x, int y,
bool flip_y, Scanline& sl, ScanlineStorage& storage)
{
#ifdef AVERAGE_BASED_SUBPIXEL_FILTERING
// The weight with which the average of the subpixels is applied to counter
// color fringes (0 = full sharpness ... 255 = grayscale anti-aliasing)
// TODO: This could be a config option, but don't forget to include the
// value in the font cache entry signature generation!
const uint8 averageWeight = 100;
const uint8 subpixelWeight = 255 - averageWeight;
const uint8* buf = (const uint8*)bitmap.buffer;
int pitch = bitmap.pitch;
sl.reset(x, x + bitmap.width / 3);
@ -420,20 +398,11 @@ decompose_ft_bitmap_subpix(const FT_Bitmap& bitmap, int x, int y,
}
} else {
const uint8* p = buf;
uint32 coverR;
uint32 coverG;
uint32 coverB;
int w = bitmap.width / 3;
for (int j = 0; j < w; j++) {
uint32 average = (p[0] + p[1] + p[2] + 2) / 3;
coverR = (p[0] * subpixelWeight + average * averageWeight) >> 8;
coverG = (p[1] * subpixelWeight + average * averageWeight) >> 8;
coverB = (p[2] * subpixelWeight + average * averageWeight) >> 8;
if (coverR || coverG || coverB)
sl.add_cell(x + j, coverR, coverG, coverB);
if (p[0] || p[1] || p[2])
sl.add_cell(x + j, p[0], p[1], p[2]);
p += 3;
}
}
@ -444,7 +413,8 @@ decompose_ft_bitmap_subpix(const FT_Bitmap& bitmap, int x, int y,
storage.render(sl);
}
}
#else // filter based anti-colored edges method
#else
// filter based anti-colored edges method
// Filtering weights
const uint8 filter[5] = { 0x10, 0x40, 0x70, 0x40, 0x10 };

View File

@ -42,6 +42,9 @@
#include "agg_scanline_storage_subpix.h"
#include "agg_scanline_u_subpix.h"
#include "agg_scanline_u_subpix_avrg_filtering.h"
#include "GlobalSubpixelSettings.h"
enum glyph_rendering {
@ -147,7 +150,11 @@ class FontEngine {
CurveConverterType fCurves;
agg::scanline_u8 fScanlineAA;
agg::scanline_bin fScanlineBin;
#ifdef AVERAGE_BASED_SUBPIXEL_FILTERING
agg::scanline_u8_subpix_avrg_filtering fScanlineSubpix;
#else
agg::scanline_u8_subpix fScanlineSubpix;
#endif
ScanlineStorageAA fScanlineStorageAA;
ScanlineStorageBin fScanlineStorageBin;

View File

@ -175,10 +175,15 @@ string_for_message_code(uint32 code, BString& string)
case AS_GET_SHOW_ALL_DRAGGERS: string = "AS_GET_SHOW_ALL_DRAGGERS"; break;
case AS_SET_SHOW_ALL_DRAGGERS: string = "AS_SET_SHOW_ALL_DRAGGERS"; break;
case AS_SET_FONT_SUBPIXEL_ANTIALIASING: string = "AS_SET_FONT_SUBPIXEL_ANTIALIASING"; break;
case AS_GET_FONT_SUBPIXEL_ANTIALIASING: string = "AS_GET_FONT_SUBPIXEL_ANTIALIASING"; break;
// Subpixel antialiasing & hinting
case AS_SET_SUBPIXEL_ANTIALIASING: string = "AS_SET_SUBPIXEL_ANTIALIASING"; break;
case AS_GET_SUBPIXEL_ANTIALIASING: string = "AS_GET_SUBPIXEL_ANTIALIASING"; break;
case AS_SET_HINTING: string = "AS_SET_HINTING"; break;
case AS_GET_HINTING: string = "AS_GET_HINTING"; break;
case AS_SET_SUBPIXEL_AVERAGE_WEIGHT: string = "AS_SET_SUBPIXEL_AVERAGE_WEIGHT"; break;
case AS_GET_SUBPIXEL_AVERAGE_WEIGHT: string = "AS_GET_SUBPIXEL_AVERAGE_WEIGHT"; break;
case AS_SET_SUBPIXEL_ORDERING: string = "AS_SET_SUBPIXEL_ORDERING"; break;
case AS_GET_SUBPIXEL_ORDERING: string = "AS_GET_SUBPIXEL_ORDERING"; break;
// Graphics calls
case AS_SET_HIGH_COLOR: string = "AS_SET_HIGH_COLOR"; break;

View File

@ -2537,22 +2537,22 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
break;
}
case AS_SET_FONT_SUBPIXEL_ANTIALIASING:
case AS_SET_SUBPIXEL_ANTIALIASING:
{
bool subpix;
if (link.Read<bool>(&subpix) == B_OK) {
LockedDesktopSettings settings(fDesktop);
settings.SetFontSubpixelAntialiasing(subpix);
settings.SetSubpixelAntialiasing(subpix);
}
fDesktop->Redraw();
break;
}
case AS_GET_FONT_SUBPIXEL_ANTIALIASING:
case AS_GET_SUBPIXEL_ANTIALIASING:
{
DesktopSettings settings(fDesktop);
fLink.StartMessage(B_OK);
fLink.Attach<bool>(settings.FontSubpixelAntialiasing());
fLink.Attach<bool>(settings.SubpixelAntialiasing());
fLink.Flush();
break;
}
@ -2576,6 +2576,46 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
fLink.Flush();
break;
}
case AS_SET_SUBPIXEL_AVERAGE_WEIGHT:
{
uint8 averageWeight;
if (link.Read<uint8>(&averageWeight) == B_OK) {
LockedDesktopSettings settings(fDesktop);
settings.SetSubpixelAverageWeight(averageWeight);
}
fDesktop->Redraw();
break;
}
case AS_GET_SUBPIXEL_AVERAGE_WEIGHT:
{
DesktopSettings settings(fDesktop);
fLink.StartMessage(B_OK);
fLink.Attach<uint8>(settings.SubpixelAverageWeight());
fLink.Flush();
break;
}
case AS_SET_SUBPIXEL_ORDERING:
{
bool subpixelOrdering;
if (link.Read<bool>(&subpixelOrdering) == B_OK) {
LockedDesktopSettings settings(fDesktop);
settings.SetSubpixelOrderingRegular(subpixelOrdering);
}
fDesktop->Redraw();
break;
}
case AS_GET_SUBPIXEL_ORDERING:
{
DesktopSettings settings(fDesktop);
fLink.StartMessage(B_OK);
fLink.Attach<bool>(settings.IsSubpixelOrderingRegular());
fLink.Flush();
break;
}
default:
printf("ServerApp %s received unhandled message code %ld\n",

File diff suppressed because it is too large Load Diff

View File

@ -17,99 +17,118 @@
namespace agg
{
//======================================================scanline_u8_subpix
//------------------------------------------------------------------------
class scanline_u8_subpix
{
public:
typedef scanline_u8_subpix self_type;
typedef int8u cover_type;
typedef int16 coord_type;
//======================================================scanline_u8_subpix
//------------------------------------------------------------------------
class scanline_u8_subpix
{
public:
typedef scanline_u8_subpix self_type;
typedef int8u cover_type;
typedef int16 coord_type;
//--------------------------------------------------------------------
struct span
{
coord_type x;
coord_type len;
cover_type* covers;
};
//--------------------------------------------------------------------
struct span
{
coord_type x;
coord_type len;
cover_type* covers;
};
typedef span* iterator;
typedef const span* const_iterator;
typedef span* iterator;
typedef const span* const_iterator;
//--------------------------------------------------------------------
scanline_u8_subpix() :
m_min_x(0),
m_last_x(0x7FFFFFF0),
m_cur_span(0)
{}
//--------------------------------------------------------------------
scanline_u8_subpix() :
m_min_x(0),
m_last_x(0x7FFFFFF0),
m_cur_span(0)
{}
//--------------------------------------------------------------------
void reset(int min_x, int max_x)
{
unsigned max_len = 3*(max_x - min_x + 2);
if(max_len > m_spans.size())
{
m_spans.resize(max_len);
m_covers.resize(max_len);
}
m_last_x = 0x7FFFFFF0;
m_min_x = min_x;
m_cur_span = &m_spans[0];
}
//--------------------------------------------------------------------
void reset(int min_x, int max_x)
{
unsigned max_len = 3*(max_x - min_x + 2);
if(max_len > m_spans.size())
{
m_spans.resize(max_len);
m_covers.resize(max_len);
}
m_last_x = 0x7FFFFFF0;
m_min_x = min_x;
m_cur_span = &m_spans[0];
}
//--------------------------------------------------------------------
void add_cell(int x, unsigned cover1, unsigned cover2, unsigned cover3)
{
x -= m_min_x;
m_covers[3*x] = (cover_type)cover1;
m_covers[3*x+1] = (cover_type)cover2;
m_covers[3*x+2] = (cover_type)cover3;
if(x == m_last_x+1)
{
m_cur_span->len += 3;
}
else
{
m_cur_span++;
m_cur_span->x = (coord_type)(x + m_min_x);
m_cur_span->len = 3;
m_cur_span->covers = &m_covers[3*x];
}
m_last_x = x;
}
//--------------------------------------------------------------------
void add_cell(int x, unsigned cover1, unsigned cover2, unsigned cover3)
{
x -= m_min_x;
m_covers[3 * x] = (cover_type)cover1;
m_covers[3 * x + 1] = (cover_type)cover2;
m_covers[3 * x + 2] = (cover_type)cover3;
if(x == m_last_x + 1)
{
m_cur_span->len += 3;
}
else
{
m_cur_span++;
m_cur_span->x = (coord_type)(x + m_min_x);
m_cur_span->len = 3;
m_cur_span->covers = &m_covers[3 * x];
}
m_last_x = x;
}
//--------------------------------------------------------------------
void finalize(int y)
{
m_y = y;
}
//--------------------------------------------------------------------
void add_span(int x, unsigned len, unsigned cover)
{
x -= m_min_x;
memset(&m_covers[3 * x], cover, 3 * len);
if(x == m_last_x+1)
{
m_cur_span->len += 3 * (coord_type)len;
}
else
{
m_cur_span++;
m_cur_span->x = (coord_type)(x + m_min_x);
m_cur_span->len = 3 * (coord_type)len;
m_cur_span->covers = &m_covers[3 * x];
}
m_last_x = x + len - 1;
}
//--------------------------------------------------------------------
void reset_spans()
{
m_last_x = 0x7FFFFFF0;
m_cur_span = &m_spans[0];
}
//--------------------------------------------------------------------
void finalize(int y)
{
m_y = y;
}
//--------------------------------------------------------------------
int y() const { return m_y; }
unsigned num_spans() const { return unsigned(m_cur_span - &m_spans[0]); }
const_iterator begin() const { return &m_spans[1]; }
iterator begin() { return &m_spans[1]; }
//--------------------------------------------------------------------
void reset_spans()
{
m_last_x = 0x7FFFFFF0;
m_cur_span = &m_spans[0];
}
private:
scanline_u8_subpix(const self_type&);
const self_type& operator = (const self_type&);
//--------------------------------------------------------------------
int y() const { return m_y; }
unsigned num_spans() const { return unsigned(m_cur_span - &m_spans[0]); }
const_iterator begin() const { return &m_spans[1]; }
iterator begin() { return &m_spans[1]; }
private:
int m_min_x;
int m_last_x;
int m_y;
pod_array<cover_type> m_covers;
pod_array<span> m_spans;
span* m_cur_span;
};
private:
scanline_u8_subpix(const self_type&);
const self_type& operator = (const self_type&);
private:
int m_min_x;
int m_last_x;
int m_y;
pod_array<cover_type> m_covers;
pod_array<span> m_spans;
span* m_cur_span;
};
}

View File

@ -25,6 +25,7 @@
# include <agg_path_storage.h>
#endif
#include "GlobalSubpixelSettings.h"
#include "GlyphLayoutEngine.h"
#include "IntRect.h"
@ -32,7 +33,9 @@
// constructor
AGGTextRenderer::AGGTextRenderer(renderer_subpix_type& subpixRenderer,
renderer_type& solidRenderer, renderer_bin_type& binRenderer,
scanline_unpacked_type& scanline)
scanline_unpacked_type& scanline,
scanline_unpacked_subpix_type& subpixScanline,
rasterizer_subpix_type& subpixRasterizer)
: fPathAdaptor()
, fGray8Adaptor()
, fGray8Scanline()
@ -47,6 +50,8 @@ AGGTextRenderer::AGGTextRenderer(renderer_subpix_type& subpixRenderer,
, fBinRenderer(binRenderer)
, fSubpixRenderer(subpixRenderer)
, fScanline(scanline)
, fSubpixScanline(subpixScanline)
, fSubpixRasterizer(subpixRasterizer)
, fRasterizer()
, fHinted(true)
@ -100,6 +105,7 @@ AGGTextRenderer::SetAntialiasing(bool antialiasing)
}
}
typedef agg::conv_transform<FontCacheEntry::CurveConverter, Transformable>
conv_font_trans_type;
@ -136,12 +142,18 @@ class AGGTextRenderer::StringRenderer {
void Start()
{
fRenderer.fRasterizer.reset();
fRenderer.fSubpixRasterizer.reset();
}
void Finish(double x, double y)
{
if (fVector) {
agg::render_scanlines(fRenderer.fRasterizer, fRenderer.fScanline,
fRenderer.fSolidRenderer);
if (gSubpixelAntialiasing) {
agg::render_scanlines(fRenderer.fSubpixRasterizer,
fRenderer.fSubpixScanline, fRenderer.fSubpixRenderer);
} else {
agg::render_scanlines(fRenderer.fRasterizer,
fRenderer.fScanline, fRenderer.fSolidRenderer);
}
}
if (fNextCharPos) {
@ -231,10 +243,22 @@ class AGGTextRenderer::StringRenderer {
case glyph_data_outline: {
fVector = true;
if (fRenderer.fContour.width() == 0.0) {
fRenderer.fRasterizer.add_path(fTransformedGlyph);
if (gSubpixelAntialiasing) {
if (fRenderer.fContour.width() == 0.0) {
fRenderer.fSubpixRasterizer.add_path(
fTransformedGlyph);
} else {
fRenderer.fSubpixRasterizer.add_path(
fTransformedContour);
}
} else {
fRenderer.fRasterizer.add_path(fTransformedContour);
if (fRenderer.fContour.width() == 0.0) {
fRenderer.fRasterizer.add_path(
fTransformedGlyph);
} else {
fRenderer.fRasterizer.add_path(
fTransformedContour);
}
}
#if SHOW_GLYPH_BOUNDS
agg::path_storage p;
@ -245,7 +269,11 @@ class AGGTextRenderer::StringRenderer {
p.close_polygon();
agg::conv_stroke<agg::path_storage> ps(p);
ps.width(1.0);
fRenderer.fRasterizer.add_path(ps);
if (gSubpixelAntialiasing) {
fRenderer.fSubpixRasterizer.add_path(ps);
} else {
fRenderer.fRasterizer.add_path(ps);
}
#endif
break;

View File

@ -25,7 +25,9 @@ class AGGTextRenderer {
AGGTextRenderer(renderer_subpix_type& subpixRenderer,
renderer_type& solidRenderer,
renderer_bin_type& binRenderer,
scanline_unpacked_type& scanline);
scanline_unpacked_type& scanline,
scanline_unpacked_subpix_type& subpixScanline,
rasterizer_subpix_type& subpixRasterizer);
virtual ~AGGTextRenderer();
void SetFont(const ServerFont &font);
@ -73,6 +75,8 @@ class AGGTextRenderer {
renderer_bin_type& fBinRenderer;
renderer_subpix_type& fSubpixRenderer;
scanline_unpacked_type& fScanline;
scanline_unpacked_subpix_type& fSubpixScanline;
rasterizer_subpix_type& fSubpixRasterizer;
rasterizer_type fRasterizer;
// NOTE: the object has it's own rasterizer object
// since it might be using a different gamma setting

View File

@ -0,0 +1,14 @@
/*
* Copyright 2008, Andrej Spielmann <andrej.spielmann@seh.ox.ac.uk>.
* All rights reserved. Distributed under the terms of the MIT License.
*/
//! Global settings of the app server regarding antialiasing and font hinting
#include "GlobalSubpixelSettings.h"
// NOTE: all these are initialized in DesktopSettings.cpp
bool gSubpixelAntialiasing;
bool gDefaultHinting;
unsigned char gSubpixelAverageWeight;
bool gSubpixelOrderingRGB;

View File

@ -0,0 +1,29 @@
/*
* Copyright 2008, Andrej Spielmann <andrej.spielmann@seh.ox.ac.uk>.
* All rights reserved. Distributed under the terms of the MIT License.
*
* Global settings of the app server regarding antialiasing and font hinting
*
*/
#ifndef GLOBAL_SUBPIXEL_SETTINGS_H
#define GLOBAL_SUBPIXEL_SETTINGS_H
#define AVERAGE_BASED_SUBPIXEL_FILTERING
extern bool gSubpixelAntialiasing;
extern bool gDefaultHinting;
// The weight with which the average of the subpixels is applied to counter
// color fringes (0 = full sharpness ... 255 = grayscale anti-aliasing)
extern unsigned char gSubpixelAverageWeight;
// There are two types of LCD displays in general - the more common have
// sub - pixels physically ordered as RGB within a pixel, but some are BGR.
// Sub - pixel antialiasing optimised for one ordering obviously doesn't work
// on the other.
extern bool gSubpixelOrderingRGB;
#endif // GLOBAL_SUBPIXEL_SETTINGS_H

View File

@ -13,6 +13,7 @@ UseFreeTypeHeaders ;
SEARCH_SOURCE += [ FDirName $(SUBDIR) drawing_modes ] ;
StaticLibrary libpainter.a :
GlobalSubpixelSettings.cpp
Painter.cpp
Transformable.cpp

View File

@ -40,6 +40,7 @@
#include <View.h>
#include "DrawingMode.h"
#include "GlobalSubpixelSettings.h"
#include "PatternHandler.h"
#include "RenderingBuffer.h"
#include "ServerBitmap.h"
@ -61,7 +62,6 @@ using std::nothrow;
#define CHECK_CLIPPING if (!fValidClipping) return BRect(0, 0, -1, -1);
#define CHECK_CLIPPING_NO_RETURN if (!fValidClipping) return;
// constructor
Painter::Painter()
: fBuffer(),
@ -69,6 +69,9 @@ Painter::Painter()
fBaseRenderer(fPixelFormat),
fUnpackedScanline(),
fPackedScanline(),
fSubpixPackedScanline(),
fSubpixUnpackedScanline(),
fSubpixRasterizer(),
fRasterizer(),
fSubpixRenderer(fBaseRenderer),
fRenderer(fBaseRenderer),
@ -90,15 +93,16 @@ Painter::Painter()
fLineCapMode(B_BUTT_CAP),
fLineJoinMode(B_MITER_JOIN),
fMiterLimit(B_DEFAULT_MITER_LIMIT),
fSubpixelAntialias(true),
fPatternHandler(),
fTextRenderer(fSubpixRenderer, fRenderer, fRendererBin, fUnpackedScanline)
fTextRenderer(fSubpixRenderer, fRenderer, fRendererBin, fUnpackedScanline,
fSubpixUnpackedScanline, fSubpixRasterizer)
{
fPixelFormat.SetDrawingMode(fDrawingMode, fAlphaSrcMode, fAlphaFncMode, false);
#if ALIASED_DRAWING
fRasterizer.gamma(agg::gamma_threshold(0.5));
fSubpixRasterizer.gamma(agg:gamma_threshold(0.5));
#endif
}
@ -211,6 +215,7 @@ Painter::ConstrainClipping(const BRegion* region)
if (fValidClipping) {
clipping_rect cb = fClippingRegion->FrameInt();
fRasterizer.clip_box(cb.left, cb.top, cb.right + 1, cb.bottom + 1);
fSubpixRasterizer.clip_box(cb.left, cb.top, cb.right + 1, cb.bottom + 1);
}
}
@ -244,13 +249,6 @@ Painter::SetDrawingMode(drawing_mode mode)
}
}
void
Painter::SetSubpixelAntialiasing(bool subpixelAntialias)
{
if (fSubpixelAntialias != subpixelAntialias) {
fSubpixelAntialias = subpixelAntialias;
}
}
// SetBlendingMode
void
@ -826,30 +824,61 @@ Painter::StrokeRoundRect(const BRect& r, float xRadius, float yRadius) const
outer.rect(lt.x, lt.y, rb.x, rb.y);
outer.radius(xRadius, yRadius);
fRasterizer.reset();
fRasterizer.add_path(outer);
if (gSubpixelAntialiasing) {
fSubpixRasterizer.reset();
fSubpixRasterizer.add_path(outer);
// don't add an inner hole if the "size is negative", this avoids some
// defects that can be observed on R5 and could be regarded as a bug.
if (2 * fPenSize < rb.x - lt.x && 2 * fPenSize < rb.y - lt.y) {
agg::rounded_rect inner;
inner.rect(lt.x + fPenSize, lt.y + fPenSize, rb.x - fPenSize,
rb.y - fPenSize);
inner.radius(max_c(0.0, xRadius - fPenSize),
max_c(0.0, yRadius - fPenSize));
// don't add an inner hole if the "size is negative", this avoids some
// defects that can be observed on R5 and could be regarded as a bug.
if (2 * fPenSize < rb.x - lt.x && 2 * fPenSize < rb.y - lt.y) {
agg::rounded_rect inner;
inner.rect(lt.x + fPenSize, lt.y + fPenSize, rb.x - fPenSize, rb.y - fPenSize);
inner.radius(max_c(0.0, xRadius - fPenSize), max_c(0.0, yRadius - fPenSize));
fSubpixRasterizer.add_path(inner);
}
fRasterizer.add_path(inner);
// make the inner rect work as a hole
fSubpixRasterizer.filling_rule(agg::fill_even_odd);
if (fPenSize > 2)
agg::render_scanlines(fSubpixRasterizer, fSubpixPackedScanline,
fSubpixRenderer);
else
agg::render_scanlines(fSubpixRasterizer, fSubpixUnpackedScanline,
fSubpixRenderer);
fSubpixRasterizer.filling_rule(agg::fill_non_zero);
} else {
fRasterizer.reset();
fRasterizer.add_path(outer);
// don't add an inner hole if the "size is negative", this avoids some
// defects that can be observed on R5 and could be regarded as a bug.
if (2 * fPenSize < rb.x - lt.x && 2 * fPenSize < rb.y - lt.y) {
agg::rounded_rect inner;
inner.rect(lt.x + fPenSize, lt.y + fPenSize, rb.x - fPenSize,
rb.y - fPenSize);
inner.radius(max_c(0.0, xRadius - fPenSize),
max_c(0.0, yRadius - fPenSize));
fRasterizer.add_path(inner);
}
// make the inner rect work as a hole
fRasterizer.filling_rule(agg::fill_even_odd);
if (fPenSize > 2)
agg::render_scanlines(fRasterizer, fPackedScanline, fRenderer);
else
agg::render_scanlines(fRasterizer, fUnpackedScanline, fRenderer);
// reset to default
fRasterizer.filling_rule(agg::fill_non_zero);
}
// make the inner rect work as a hole
fRasterizer.filling_rule(agg::fill_even_odd);
if (fPenSize > 2)
agg::render_scanlines(fRasterizer, fPackedScanline, fRenderer);
else
agg::render_scanlines(fRasterizer, fUnpackedScanline, fRenderer);
// reset to default
fRasterizer.filling_rule(agg::fill_non_zero);
return _Clipped(_BoundingBox(outer));
}
}
@ -932,20 +961,39 @@ Painter::DrawEllipse(BRect r, bool fill) const
yRadius + inset,
divisions);
fRasterizer.reset();
fRasterizer.add_path(outer);
fRasterizer.add_path(inner);
if (gSubpixelAntialiasing) {
fSubpixRasterizer.reset();
fSubpixRasterizer.add_path(outer);
fSubpixRasterizer.add_path(inner);
// make the inner ellipse work as a hole
fRasterizer.filling_rule(agg::fill_even_odd);
// make the inner ellipse work as a hole
fSubpixRasterizer.filling_rule(agg::fill_even_odd);
if (fPenSize > 4)
agg::render_scanlines(fRasterizer, fPackedScanline, fRenderer);
else
agg::render_scanlines(fRasterizer, fUnpackedScanline, fRenderer);
if (fPenSize > 4)
agg::render_scanlines(fSubpixRasterizer, fSubpixPackedScanline,
fSubpixRenderer);
else
agg::render_scanlines(fSubpixRasterizer, fSubpixUnpackedScanline,
fSubpixRenderer);
// reset to default
fRasterizer.filling_rule(agg::fill_non_zero);
// reset to default
fSubpixRasterizer.filling_rule(agg::fill_non_zero);
} else {
fRasterizer.reset();
fRasterizer.add_path(outer);
fRasterizer.add_path(inner);
// make the inner ellipse work as a hole
fRasterizer.filling_rule(agg::fill_even_odd);
if (fPenSize > 4)
agg::render_scanlines(fRasterizer, fPackedScanline, fRenderer);
else
agg::render_scanlines(fRasterizer, fUnpackedScanline, fRenderer);
// reset to default
fRasterizer.filling_rule(agg::fill_non_zero);
}
return _Clipped(_BoundingBox(outer));
}
@ -1131,6 +1179,7 @@ Painter::InvertRect(const BRect& r) const
return _Clipped(r);
}
// #pragma mark - private
// _Transform
@ -1968,10 +2017,20 @@ Painter::_StrokePath(VertexSource& path) const
stroke.line_join(agg_line_join_mode_for(fLineJoinMode));
stroke.miter_limit(fMiterLimit);
fRasterizer.reset();
fRasterizer.add_path(stroke);
if (gSubpixelAntialiasing) {
fSubpixRasterizer.reset();
fSubpixRasterizer.add_path(stroke);
agg::render_scanlines(fSubpixRasterizer,
fSubpixPackedScanline, fSubpixRenderer);
} else {
agg::render_scanlines(fRasterizer, fPackedScanline, fRenderer);
fRasterizer.reset();
fRasterizer.add_path(stroke);
agg::render_scanlines(fRasterizer, fPackedScanline, fRenderer);
}
BRect touched = _BoundingBox(path);
float penSize = ceilf(fPenSize / 2.0);
@ -1985,9 +2044,17 @@ template<class VertexSource>
BRect
Painter::_FillPath(VertexSource& path) const
{
fRasterizer.reset();
fRasterizer.add_path(path);
agg::render_scanlines(fRasterizer, fPackedScanline, fRenderer);
if (gSubpixelAntialiasing) {
fSubpixRasterizer.reset();
fSubpixRasterizer.add_path(path);
agg::render_scanlines(fSubpixRasterizer,
fSubpixPackedScanline, fSubpixRenderer);
} else {
fRasterizer.reset();
fRasterizer.add_path(path);
agg::render_scanlines(fRasterizer, fPackedScanline, fRenderer);
}
return _Clipped(_BoundingBox(path));
}

View File

@ -7,6 +7,7 @@
* rendering pipe-lines for stroke, fills, bitmap and text rendering.
*
*/
#ifndef PAINTER_H
#define PAINTER_H
@ -23,7 +24,6 @@
#include <Font.h>
#include <Rect.h>
class BBitmap;
class BRegion;
class DrawState;
@ -73,9 +73,6 @@ class Painter {
void SetDrawingMode(drawing_mode mode);
inline drawing_mode DrawingMode() const
{ return fDrawingMode; }
void SetSubpixelAntialiasing(bool subpixelAntialias);
bool SubpixelAntialiasing() const
{ return fSubpixelAntialias; }
void SetBlendingMode(source_alpha srcAlpha,
alpha_function alphaFunc);
@ -272,6 +269,9 @@ mutable renderer_base fBaseRenderer;
mutable scanline_unpacked_type fUnpackedScanline;
mutable scanline_packed_type fPackedScanline;
mutable scanline_packed_subpix_type fSubpixPackedScanline;
mutable scanline_unpacked_subpix_type fSubpixUnpackedScanline;
mutable rasterizer_subpix_type fSubpixRasterizer;
mutable rasterizer_type fRasterizer;
mutable renderer_subpix_type fSubpixRenderer;
mutable renderer_type fRenderer;
@ -294,7 +294,6 @@ mutable agg::conv_curve<agg::path_storage> fCurve;
cap_mode fLineCapMode;
join_mode fLineJoinMode;
float fMiterLimit;
bool fSubpixelAntialias;
PatternHandler fPatternHandler;

View File

@ -0,0 +1,547 @@
/*
* Copyright 2008, Andrej Spielmann <andrej.spielmann@seh.ox.ac.uk>.
* All rights reserved. Distributed under the terms of the MIT License.
*
* Copyright 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
*
*
*/
#ifndef AGG_RASTERIZER_SCANLINE_AA_SUBPIX_INCLUDED
#define AGG_RASTERIZER_SCANLINE_AA_SUBPIX_INCLUDED
#include "agg_rasterizer_cells_aa.h"
#include "agg_rasterizer_sl_clip.h"
#include "agg_gamma_functions.h"
namespace agg
{
template<class Clip=rasterizer_sl_clip_int> class rasterizer_scanline_aa_subpix
{
enum status
{
status_initial,
status_move_to,
status_line_to,
status_closed
};
public:
typedef Clip clip_type;
typedef typename Clip::conv_type conv_type;
typedef typename Clip::coord_type coord_type;
enum aa_scale_e
{
aa_shift = 8,
aa_scale = 1 << aa_shift,
aa_mask = aa_scale - 1,
aa_scale2 = aa_scale * 2,
aa_mask2 = aa_scale2 - 1
};
//--------------------------------------------------------------------
rasterizer_scanline_aa_subpix() :
m_outline(),
m_clipper(),
m_filling_rule(fill_non_zero),
m_auto_close(true),
m_start_x(0),
m_start_y(0),
m_status(status_initial)
{
int i;
for(i = 0; i < aa_scale; i++) m_gamma[i] = i;
}
//--------------------------------------------------------------------
template<class GammaF>
rasterizer_scanline_aa_subpix(const GammaF& gamma_function) :
m_outline(),
m_clipper(m_outline),
m_filling_rule(fill_non_zero),
m_auto_close(true),
m_start_x(0),
m_start_y(0),
m_status(status_initial)
{
gamma(gamma_function);
}
//--------------------------------------------------------------------
void reset();
void reset_clipping();
void clip_box(double x1, double y1, double x2, double y2);
void filling_rule(filling_rule_e filling_rule);
void auto_close(bool flag) { m_auto_close = flag; }
//--------------------------------------------------------------------
template<class GammaF> void gamma(const GammaF& gamma_function)
{
int i;
for(i = 0; i < aa_scale; i++)
{
m_gamma[i] = uround(gamma_function(double(i) / aa_mask) * aa_mask);
}
}
//--------------------------------------------------------------------
unsigned apply_gamma(unsigned cover) const
{
return m_gamma[cover];
}
//--------------------------------------------------------------------
void move_to(int x, int y);
void line_to(int x, int y);
void move_to_d(double x, double y);
void line_to_d(double x, double y);
void close_polygon();
void add_vertex(double x, double y, unsigned cmd);
void edge(int x1, int y1, int x2, int y2);
void edge_d(double x1, double y1, double x2, double y2);
//-------------------------------------------------------------------
template<class VertexSource>
void add_path(VertexSource& vs, unsigned path_id=0)
{
double x;
double y;
unsigned cmd;
vs.rewind(path_id);
if(m_outline.sorted()) reset();
while(!is_stop(cmd = vs.vertex(&x, &y)))
{
if (is_vertex(cmd)) {
x *= 3;
}
add_vertex(x, y, cmd);
}
}
//--------------------------------------------------------------------
int min_x() const { return m_outline.min_x() / 3; }
int min_y() const { return m_outline.min_y(); }
int max_x() const { return m_outline.max_x() / 3; }
int max_y() const { return m_outline.max_y(); }
//--------------------------------------------------------------------
void sort();
bool rewind_scanlines();
bool navigate_scanline(int y);
//--------------------------------------------------------------------
AGG_INLINE unsigned calculate_alpha(int area) const
{
int cover = area >> (poly_subpixel_shift*2 + 1 - aa_shift);
if(cover < 0) cover = -cover;
if(m_filling_rule == fill_even_odd)
{
cover &= aa_mask2;
if(cover > aa_scale)
{
cover = aa_scale2 - cover;
}
}
if(cover > aa_mask) cover = aa_mask;
return m_gamma[cover];
}
//--------------------------------------------------------------------
template<class Scanline> bool sweep_scanline(Scanline& sl)
{
for(;;)
{
if(m_scan_y > m_outline.max_y()) return false;
sl.reset_spans();
unsigned num_cells = m_outline.scanline_num_cells(m_scan_y);
const cell_aa* const* cells = m_outline.scanline_cells(m_scan_y);
int cover = 0;
int cover2 = 0;
int cover3 = 0;
while(num_cells)
{
const cell_aa* cur_cell = *cells;
int x = cur_cell->x;
int area1 = cur_cell->area;
int area2;
int area3;
unsigned alpha1;
unsigned alpha2;
unsigned alpha3;
int last_cover = cover3;
cover = cover3;
cover += cur_cell->cover;
while(--num_cells)
{
cur_cell = *++cells;
if(cur_cell->x != x) break;
area1 += cur_cell->area;
cover += cur_cell->cover;
}
if (x % 3 == 0)
{
if (cur_cell->x == x + 1)
{
area2 = cur_cell->area;
cover2 = cover + cur_cell->cover;
while (--num_cells)
{
cur_cell = *++cells;
if (cur_cell->x != x+1) break;
area2 += cur_cell->area;
cover2 += cur_cell->cover;
}
}
else
{
area2 = 0;
cover2 = cover;
}
if (cur_cell->x == x + 2)
{
area3 = cur_cell->area;
cover3 = cover2 + cur_cell->cover;
while (--num_cells)
{
cur_cell = *++cells;
if (cur_cell->x != x+2) break;
area3 += cur_cell->area;
cover3 += cur_cell->cover;
}
}
else
{
area3 = 0;
cover3 = cover2;
}
}
else if (x % 3 == 1)
{
area2 = area1;
area1 = 0;
cover2 = cover;
cover = last_cover;
if (cur_cell->x == x+1)
{
area3 = cur_cell->area;
cover3 = cover2 + cur_cell->cover;
while (--num_cells)
{
cur_cell = *++cells;
if (cur_cell->x != x+1) break;
area3 += cur_cell->area;
cover3 += cur_cell->cover;
}
}
else
{
area3 = 0;
cover3 = cover2;
}
}
else // if (x % 3 == 2)
{
area3 = area1;
area2 = 0;
area1 = 0;
cover3 = cover;
cover = last_cover;
cover2 = last_cover;
}
alpha1 = area1 ? calculate_alpha((cover
<< (poly_subpixel_shift + 1)) - area1) : 0;
alpha2 = area2 ? calculate_alpha((cover2
<< (poly_subpixel_shift + 1)) - area2) : 0;
alpha3 = area3 ? calculate_alpha((cover3
<< (poly_subpixel_shift + 1)) - area3) : 0;
if(alpha1 || alpha2 || alpha3)
{
x += 3 - (x % 3);
if (area1 && !area2 && area3)
{
alpha2 = calculate_alpha(cover
<< (poly_subpixel_shift + 1));
}
else if (num_cells && cur_cell->x >= x)
{
if (area1 && !area2)
{
alpha2 = calculate_alpha(cover
<< (poly_subpixel_shift + 1));
alpha3 = alpha2;
}
if (area2 && !area3)
{
alpha3 = calculate_alpha(cover2
<< (poly_subpixel_shift + 1));
}
}
if (!area1)
{
if (area2)
{
alpha1 = calculate_alpha(cover
<< (poly_subpixel_shift + 1));
}
else if (area3)
{
alpha2 = calculate_alpha(cover
<< (poly_subpixel_shift + 1));
alpha1 = alpha2;
}
}
sl.add_cell(x / 3 - 1, alpha1, alpha2, alpha3);
}
if (num_cells && cur_cell->x - x >= 3)
{
alpha1 = calculate_alpha(cover3
<< (poly_subpixel_shift + 1));
sl.add_span(x / 3, cur_cell->x / 3 - x / 3, alpha1);
}
}
if(sl.num_spans()) break;
++m_scan_y;
}
sl.finalize(m_scan_y);
++m_scan_y;
return true;
}
//--------------------------------------------------------------------
bool hit_test(int tx, int ty);
private:
//--------------------------------------------------------------------
// Disable copying
rasterizer_scanline_aa_subpix(const rasterizer_scanline_aa_subpix<Clip>&);
const rasterizer_scanline_aa_subpix<Clip>&
operator = (const rasterizer_scanline_aa_subpix<Clip>&);
private:
rasterizer_cells_aa<cell_aa> m_outline;
clip_type m_clipper;
int m_gamma[aa_scale];
filling_rule_e m_filling_rule;
bool m_auto_close;
coord_type m_start_x;
coord_type m_start_y;
unsigned m_status;
int m_scan_y;
};
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa_subpix<Clip>::reset()
{
m_outline.reset();
m_status = status_initial;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa_subpix<Clip>::filling_rule(filling_rule_e filling_rule)
{
m_filling_rule = filling_rule;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa_subpix<Clip>::clip_box(double x1, double y1,
double x2, double y2)
{
reset();
m_clipper.clip_box(3 * conv_type::downscale(x1), conv_type::upscale(y1),
conv_type::upscale(3 * x2), conv_type::upscale(y2));
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa_subpix<Clip>::reset_clipping()
{
reset();
m_clipper.reset_clipping();
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa_subpix<Clip>::close_polygon()
{
if(m_status == status_line_to)
{
m_clipper.line_to(m_outline, m_start_x, m_start_y);
m_status = status_closed;
}
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa_subpix<Clip>::move_to(int x, int y)
{
if(m_outline.sorted()) reset();
if(m_auto_close) close_polygon();
m_clipper.move_to(m_start_x = conv_type::downscale(x),
m_start_y = conv_type::downscale(y));
m_status = status_move_to;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa_subpix<Clip>::line_to(int x, int y)
{
m_clipper.line_to(m_outline,
conv_type::downscale(x),
conv_type::downscale(y));
m_status = status_line_to;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa_subpix<Clip>::move_to_d(double x, double y)
{
if(m_outline.sorted()) reset();
if(m_auto_close) close_polygon();
m_clipper.move_to(m_start_x = conv_type::upscale(x),
m_start_y = conv_type::upscale(y));
m_status = status_move_to;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa_subpix<Clip>::line_to_d(double x, double y)
{
m_clipper.line_to(m_outline,
conv_type::upscale(x),
conv_type::upscale(y));
m_status = status_line_to;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa_subpix<Clip>::add_vertex(double x, double y, unsigned cmd)
{
if(is_move_to(cmd))
{
move_to_d(x, y);
}
else
if(is_vertex(cmd))
{
line_to_d(x, y);
}
else
if(is_close(cmd))
{
close_polygon();
}
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa_subpix<Clip>::edge(int x1, int y1, int x2, int y2)
{
if(m_outline.sorted()) reset();
m_clipper.move_to(conv_type::downscale(x1), conv_type::downscale(y1));
m_clipper.line_to(m_outline,
conv_type::downscale(x2),
conv_type::downscale(y2));
m_status = status_move_to;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa_subpix<Clip>::edge_d(double x1, double y1,
double x2, double y2)
{
if(m_outline.sorted()) reset();
m_clipper.move_to(conv_type::upscale(x1), conv_type::upscale(y1));
m_clipper.line_to(m_outline,
conv_type::upscale(x2),
conv_type::upscale(y2));
m_status = status_move_to;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa_subpix<Clip>::sort()
{
m_outline.sort_cells();
}
//------------------------------------------------------------------------
template<class Clip>
AGG_INLINE bool rasterizer_scanline_aa_subpix<Clip>::rewind_scanlines()
{
if(m_auto_close) close_polygon();
m_outline.sort_cells();
if(m_outline.total_cells() == 0)
{
return false;
}
m_scan_y = m_outline.min_y();
return true;
}
//------------------------------------------------------------------------
template<class Clip>
AGG_INLINE bool rasterizer_scanline_aa_subpix<Clip>::navigate_scanline(int y)
{
if(m_auto_close) close_polygon();
m_outline.sort_cells();
if(m_outline.total_cells() == 0 ||
y < m_outline.min_y() ||
y > m_outline.max_y())
{
return false;
}
m_scan_y = y;
return true;
}
//------------------------------------------------------------------------
template<class Clip>
bool rasterizer_scanline_aa_subpix<Clip>::hit_test(int tx, int ty)
{
if(!navigate_scanline(ty)) return false;
scanline_hit_test sl(tx);
sweep_scanline(sl);
return sl.hit();
}
}
#endif

View File

@ -23,339 +23,327 @@
namespace agg
{
//----------------------------------------------------------renderer_region
template<class PixelFormat> class renderer_region
{
public:
typedef PixelFormat pixfmt_type;
typedef typename pixfmt_type::color_type color_type;
typedef renderer_base<pixfmt_type> base_ren_type;
//--------------------------------------------------------------------
renderer_region(pixfmt_type& ren) :
m_ren(ren),
m_region(NULL),
m_curr_cb(0),
m_bounds(m_ren.xmin(), m_ren.ymin(), m_ren.xmax(), m_ren.ymax())
{
}
//--------------------------------------------------------------------
const pixfmt_type& ren() const { return m_ren.ren(); }
pixfmt_type& ren() { return m_ren.ren(); }
//--------------------------------------------------------------------
unsigned width() const { return m_ren.width(); }
unsigned height() const { return m_ren.height(); }
//--------------------------------------------------------------------
const rect_i& clip_box() const { return m_ren.clip_box(); }
int xmin() const { return m_ren.xmin(); }
int ymin() const { return m_ren.ymin(); }
int xmax() const { return m_ren.xmax(); }
int ymax() const { return m_ren.ymax(); }
//--------------------------------------------------------------------
const rect_i& bounding_clip_box() const { return m_bounds; }
int bounding_xmin() const { return m_bounds.x1; }
int bounding_ymin() const { return m_bounds.y1; }
int bounding_xmax() const { return m_bounds.x2; }
int bounding_ymax() const { return m_bounds.y2; }
//--------------------------------------------------------------------
void first_clip_box()
{
m_curr_cb = 0;
if(m_region && m_region->CountRects() > 0)
{
clipping_rect cb = m_region->RectAtInt(0);
m_ren.clip_box_naked(cb.left, cb.top, cb.right, cb.bottom);
}
else
m_ren.clip_box_naked(0, 0, -1, -1);
}
//--------------------------------------------------------------------
bool next_clip_box()
{
if(m_region && (int)(++m_curr_cb) < m_region->CountRects())
{
clipping_rect cb = m_region->RectAtInt(m_curr_cb);
m_ren.clip_box_naked(cb.left, cb.top, cb.right, cb.bottom);
return true;
}
return false;
}
//--------------------------------------------------------------------
void reset_clipping(bool visibility)
{
m_ren.reset_clipping(visibility);
m_region = NULL;
m_curr_cb = 0;
m_bounds = m_ren.clip_box();
}
//--------------------------------------------------------------------
void set_clipping_region(BRegion* region)
{
m_region = region;
if (m_region) {
clipping_rect r = m_region->FrameInt();
if (r.left <= r.right && r.top <= r.bottom) {
// clip rect_i to frame buffer bounds
r.left = max_c(0, r.left);
r.top = max_c(0, r.top);
r.right = min_c((int)width() - 1, r.right);
r.bottom = min_c((int)height() - 1, r.bottom);
if(r.left < m_bounds.x1) m_bounds.x1 = r.left;
if(r.top < m_bounds.y1) m_bounds.y1 = r.top;
if(r.right > m_bounds.x2) m_bounds.x2 = r.right;
if(r.bottom > m_bounds.y2) m_bounds.y2 = r.bottom;
}
}
}
//--------------------------------------------------------------------
void clear(const color_type& c)
{
m_ren.clear(c);
}
//--------------------------------------------------------------------
void copy_pixel(int x, int y, const color_type& c)
{
first_clip_box();
do
{
if(m_ren.inbox(x, y))
{
m_ren.ren().copy_pixel(x, y, c);
break;
}
}
while(next_clip_box());
}
//--------------------------------------------------------------------
void blend_pixel(int x, int y, const color_type& c, cover_type cover)
{
first_clip_box();
do
{
if(m_ren.inbox(x, y))
{
m_ren.ren().blend_pixel(x, y, c, cover);
break;
}
}
while(next_clip_box());
}
//--------------------------------------------------------------------
color_type pixel(int x, int y) const
{
first_clip_box();
do
{
if(m_ren.inbox(x, y))
{
return m_ren.ren().pixel(x, y);
}
}
while(next_clip_box());
return color_type::no_color();
}
//--------------------------------------------------------------------
void copy_hline(int x1, int y, int x2, const color_type& c)
{
first_clip_box();
do
{
m_ren.copy_hline(x1, y, x2, c);
}
while(next_clip_box());
}
//--------------------------------------------------------------------
void copy_vline(int x, int y1, int y2, const color_type& c)
{
first_clip_box();
do
{
m_ren.copy_vline(x, y1, y2, c);
}
while(next_clip_box());
}
//--------------------------------------------------------------------
void blend_hline(int x1, int y, int x2,
const color_type& c, cover_type cover)
{
first_clip_box();
do
{
m_ren.blend_hline(x1, y, x2, c, cover);
}
while(next_clip_box());
}
//----------------------------------------------------------renderer_region
template<class PixelFormat> class renderer_region
{
public:
typedef PixelFormat pixfmt_type;
typedef typename pixfmt_type::color_type color_type;
typedef renderer_base<pixfmt_type> base_ren_type;
//--------------------------------------------------------------------
void blend_hline_subpix(int x1, int y, int x2,
const color_type& c, cover_type cover)
{
first_clip_box();
do
{
m_ren.blend_hline_subpix(x1, y, x2, c, cover);
}
while(next_clip_box());
}
//--------------------------------------------------------------------
void blend_vline(int x, int y1, int y2,
const color_type& c, cover_type cover)
{
first_clip_box();
do
{
m_ren.blend_vline(x, y1, y2, c, cover);
}
while(next_clip_box());
}
//--------------------------------------------------------------------
void copy_bar(int x1, int y1, int x2, int y2, const color_type& c)
{
first_clip_box();
do
{
m_ren.copy_bar(x1, y1, x2, y2, c);
}
while(next_clip_box());
}
//--------------------------------------------------------------------
void blend_bar(int x1, int y1, int x2, int y2,
const color_type& c, cover_type cover)
{
first_clip_box();
do
{
m_ren.blend_bar(x1, y1, x2, y2, c, cover);
}
while(next_clip_box());
}
//--------------------------------------------------------------------
void blend_solid_hspan(int x, int y, int len,
const color_type& c, const cover_type* covers)
{
first_clip_box();
do
{
m_ren.blend_solid_hspan(x, y, len, c, covers);
}
while(next_clip_box());
}
renderer_region(pixfmt_type& ren) :
m_ren(ren),
m_region(NULL),
m_curr_cb(0),
m_bounds(m_ren.xmin(), m_ren.ymin(), m_ren.xmax(), m_ren.ymax())
{
}
//--------------------------------------------------------------------
void blend_solid_hspan_subpix(int x, int y, int len,
const color_type& c, const cover_type* covers)
{
first_clip_box();
do
{
m_ren.blend_solid_hspan_subpix(x, y, len, c, covers);
}
while(next_clip_box());
}
const pixfmt_type& ren() const { return m_ren.ren(); }
pixfmt_type& ren() { return m_ren.ren(); }
//--------------------------------------------------------------------
void blend_solid_vspan(int x, int y, int len,
const color_type& c, const cover_type* covers)
{
first_clip_box();
do
{
m_ren.blend_solid_vspan(x, y, len, c, covers);
}
while(next_clip_box());
}
//--------------------------------------------------------------------
unsigned width() const { return m_ren.width(); }
unsigned height() const { return m_ren.height(); }
//--------------------------------------------------------------------
void blend_color_hspan(int x, int y, int len,
const color_type* colors,
const cover_type* covers,
cover_type cover = cover_full)
{
first_clip_box();
do
{
m_ren.blend_color_hspan(x, y, len, colors, covers, cover);
}
while(next_clip_box());
}
//--------------------------------------------------------------------
const rect_i& clip_box() const { return m_ren.clip_box(); }
int xmin() const { return m_ren.xmin(); }
int ymin() const { return m_ren.ymin(); }
int xmax() const { return m_ren.xmax(); }
int ymax() const { return m_ren.ymax(); }
//--------------------------------------------------------------------
void blend_color_vspan(int x, int y, int len,
const color_type* colors,
const cover_type* covers,
cover_type cover = cover_full)
{
first_clip_box();
do
{
m_ren.blend_color_hspan(x, y, len, colors, covers, cover);
}
while(next_clip_box());
}
//--------------------------------------------------------------------
const rect_i& bounding_clip_box() const { return m_bounds; }
int bounding_xmin() const { return m_bounds.x1; }
int bounding_ymin() const { return m_bounds.y1; }
int bounding_xmax() const { return m_bounds.x2; }
int bounding_ymax() const { return m_bounds.y2; }
//--------------------------------------------------------------------
void blend_color_hspan_no_clip(int x, int y, int len,
const color_type* colors,
const cover_type* covers,
cover_type cover = cover_full)
{
m_ren.blend_color_hspan_no_clip(x, y, len, colors, covers, cover);
}
//--------------------------------------------------------------------
void first_clip_box()
{
m_curr_cb = 0;
if(m_region && m_region->CountRects() > 0)
{
clipping_rect cb = m_region->RectAtInt(0);
m_ren.clip_box_naked(cb.left, cb.top, cb.right, cb.bottom);
}
else
m_ren.clip_box_naked(0, 0, -1, -1);
}
//--------------------------------------------------------------------
void blend_color_vspan_no_clip(int x, int y, int len,
const color_type* colors,
const cover_type* covers,
cover_type cover = cover_full)
{
m_ren.blend_color_vspan_no_clip(x, y, len, colors, covers, cover);
}
//--------------------------------------------------------------------
bool next_clip_box()
{
if(m_region && (int)(++m_curr_cb) < m_region->CountRects())
{
clipping_rect cb = m_region->RectAtInt(m_curr_cb);
m_ren.clip_box_naked(cb.left, cb.top, cb.right, cb.bottom);
return true;
}
return false;
}
//--------------------------------------------------------------------
void copy_from(const rendering_buffer& from,
const rect_i* rc=0,
int x_to=0,
int y_to=0)
{
first_clip_box();
do
{
m_ren.copy_from(from, rc, x_to, y_to);
}
while(next_clip_box());
}
//--------------------------------------------------------------------
void reset_clipping(bool visibility)
{
m_ren.reset_clipping(visibility);
m_region = NULL;
m_curr_cb = 0;
m_bounds = m_ren.clip_box();
}
private:
renderer_region(const renderer_region<PixelFormat>&);
const renderer_region<PixelFormat>&
operator = (const renderer_region<PixelFormat>&);
//--------------------------------------------------------------------
void set_clipping_region(BRegion* region)
{
m_region = region;
if (m_region) {
clipping_rect r = m_region->FrameInt();
if (r.left <= r.right && r.top <= r.bottom) {
// clip rect_i to frame buffer bounds
r.left = max_c(0, r.left);
r.top = max_c(0, r.top);
r.right = min_c((int)width() - 1, r.right);
r.bottom = min_c((int)height() - 1, r.bottom);
base_ren_type m_ren;
if(r.left < m_bounds.x1) m_bounds.x1 = r.left;
if(r.top < m_bounds.y1) m_bounds.y1 = r.top;
if(r.right > m_bounds.x2) m_bounds.x2 = r.right;
if(r.bottom > m_bounds.y2) m_bounds.y2 = r.bottom;
}
}
}
//--------------------------------------------------------------------
void clear(const color_type& c)
{
m_ren.clear(c);
}
//--------------------------------------------------------------------
void copy_pixel(int x, int y, const color_type& c)
{
first_clip_box();
do
{
if(m_ren.inbox(x, y))
{
m_ren.ren().copy_pixel(x, y, c);
break;
}
}
while(next_clip_box());
}
//--------------------------------------------------------------------
void blend_pixel(int x, int y, const color_type& c, cover_type cover)
{
first_clip_box();
do
{
if(m_ren.inbox(x, y))
{
m_ren.ren().blend_pixel(x, y, c, cover);
break;
}
}
while(next_clip_box());
}
//--------------------------------------------------------------------
color_type pixel(int x, int y) const
{
first_clip_box();
do
{
if(m_ren.inbox(x, y))
{
return m_ren.ren().pixel(x, y);
}
}
while(next_clip_box());
return color_type::no_color();
}
//--------------------------------------------------------------------
void copy_hline(int x1, int y, int x2, const color_type& c)
{
first_clip_box();
do
{
m_ren.copy_hline(x1, y, x2, c);
}
while(next_clip_box());
}
//--------------------------------------------------------------------
void copy_vline(int x, int y1, int y2, const color_type& c)
{
first_clip_box();
do
{
m_ren.copy_vline(x, y1, y2, c);
}
while(next_clip_box());
}
//--------------------------------------------------------------------
void blend_hline(int x1, int y, int x2,
const color_type& c, cover_type cover)
{
first_clip_box();
do
{
m_ren.blend_hline(x1, y, x2, c, cover);
}
while(next_clip_box());
}
//--------------------------------------------------------------------
void blend_vline(int x, int y1, int y2,
const color_type& c, cover_type cover)
{
first_clip_box();
do
{
m_ren.blend_vline(x, y1, y2, c, cover);
}
while(next_clip_box());
}
//--------------------------------------------------------------------
void copy_bar(int x1, int y1, int x2, int y2, const color_type& c)
{
first_clip_box();
do
{
m_ren.copy_bar(x1, y1, x2, y2, c);
}
while(next_clip_box());
}
//--------------------------------------------------------------------
void blend_bar(int x1, int y1, int x2, int y2,
const color_type& c, cover_type cover)
{
first_clip_box();
do
{
m_ren.blend_bar(x1, y1, x2, y2, c, cover);
}
while(next_clip_box());
}
//--------------------------------------------------------------------
void blend_solid_hspan(int x, int y, int len,
const color_type& c, const cover_type* covers)
{
first_clip_box();
do
{
m_ren.blend_solid_hspan(x, y, len, c, covers);
}
while(next_clip_box());
}
//--------------------------------------------------------------------
void blend_solid_hspan_subpix(int x, int y, int len,
const color_type& c, const cover_type* covers)
{
first_clip_box();
do
{
m_ren.blend_solid_hspan_subpix(x, y, len, c, covers);
}
while(next_clip_box());
}
//--------------------------------------------------------------------
void blend_solid_vspan(int x, int y, int len,
const color_type& c, const cover_type* covers)
{
first_clip_box();
do
{
m_ren.blend_solid_vspan(x, y, len, c, covers);
}
while(next_clip_box());
}
//--------------------------------------------------------------------
void blend_color_hspan(int x, int y, int len,
const color_type* colors,
const cover_type* covers,
cover_type cover = cover_full)
{
first_clip_box();
do
{
m_ren.blend_color_hspan(x, y, len, colors, covers, cover);
}
while(next_clip_box());
}
//--------------------------------------------------------------------
void blend_color_vspan(int x, int y, int len,
const color_type* colors,
const cover_type* covers,
cover_type cover = cover_full)
{
first_clip_box();
do
{
m_ren.blend_color_hspan(x, y, len, colors, covers, cover);
}
while(next_clip_box());
}
//--------------------------------------------------------------------
void blend_color_hspan_no_clip(int x, int y, int len,
const color_type* colors,
const cover_type* covers,
cover_type cover = cover_full)
{
m_ren.blend_color_hspan_no_clip(x, y, len, colors, covers, cover);
}
//--------------------------------------------------------------------
void blend_color_vspan_no_clip(int x, int y, int len,
const color_type* colors,
const cover_type* covers,
cover_type cover = cover_full)
{
m_ren.blend_color_vspan_no_clip(x, y, len, colors, covers, cover);
}
//--------------------------------------------------------------------
void copy_from(const rendering_buffer& from,
const rect_i* rc=0,
int x_to=0,
int y_to=0)
{
first_clip_box();
do
{
m_ren.copy_from(from, rc, x_to, y_to);
}
while(next_clip_box());
}
private:
renderer_region(const renderer_region<PixelFormat>&);
const renderer_region<PixelFormat>&
operator = (const renderer_region<PixelFormat>&);
base_ren_type m_ren;
BRegion* m_region;
unsigned m_curr_cb;
rect_i m_bounds;
};
unsigned m_curr_cb;
rect_i m_bounds;
};
}

View File

@ -18,68 +18,66 @@
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();
//============================================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;
}
}
for(;;)
{
int x = span->x;
if(span->len > 0)
{
ren.blend_solid_hspan_subpix(x, y, (unsigned)span->len,
color,
span->covers);
}
else
{
ren.blend_hline(x, y, (unsigned)(x - (span->len / 3) - 1),
color,
*(span->covers));
}
if(--num_spans == 0) break;
++span;
}
}
//==========================================renderer_scanline_subpix_solid
template<class 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
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;
}
//--------------------------------------------------------------------
renderer_scanline_subpix_solid() : m_ren(0) {}
renderer_scanline_subpix_solid(base_ren_type& ren) : m_ren(&ren) {}
void attach(base_ren_type& ren)
{
m_ren = &ren;
}
//--------------------------------------------------------------------
void color(const color_type& c) { m_color = c; }
const color_type& color() const { return m_color; }
//--------------------------------------------------------------------
void color(const color_type& c) { m_color = c; }
const color_type& color() const { return m_color; }
//--------------------------------------------------------------------
void prepare() {}
//--------------------------------------------------------------------
void prepare() {}
//--------------------------------------------------------------------
template<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;
};
//--------------------------------------------------------------------
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;
};
}

View File

@ -0,0 +1,167 @@
/*
* Copyright 2008, Andrej Spielmann <andrej.spielmann@seh.ox.ac.uk>.
* All rights reserved. Distributed under the terms of the MIT License.
*
* Copyright 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
*
*
* Class scanline_p8_subpix_avrg_filtering, a slightly modified version of
* scanline_p8 customized to store 3 covers per pixel
*
*/
#ifndef AGG_SCANLINE_P_SUBPIX_INCLUDED
#define AGG_SCANLINE_P_SUBPIX_INCLUDED
#include "agg_array.h"
namespace agg
{
//======================================================scanline_p8_subpix
//
// This is a general purpose scaline container which supports the interface
// used in the rasterizer::render(). See description of scanline_u8
// for details.
//
//------------------------------------------------------------------------
class scanline_p8_subpix
{
public:
typedef scanline_p8_subpix self_type;
typedef int8u cover_type;
typedef int16 coord_type;
//--------------------------------------------------------------------
struct span
{
coord_type x;
coord_type len; // If negative, it's a solid span, covers is valid
const cover_type* covers;
};
typedef span* iterator;
typedef const span* const_iterator;
scanline_p8_subpix() :
m_last_x(0x7FFFFFF0),
m_covers(),
m_cover_ptr(0),
m_spans(),
m_cur_span(0)
{
}
//--------------------------------------------------------------------
void reset(int min_x, int max_x)
{
unsigned max_len = 3*(max_x - min_x + 3);
if(max_len > m_spans.size())
{
m_spans.resize(max_len);
m_covers.resize(max_len);
}
m_last_x = 0x7FFFFFF0;
m_cover_ptr = &m_covers[0];
m_cur_span = &m_spans[0];
m_cur_span->len = 0;
}
//--------------------------------------------------------------------
void add_cell(int x, unsigned cover1, unsigned cover2, unsigned cover3)
{
m_cover_ptr[0] = (cover_type)cover1;
m_cover_ptr[1] = (cover_type)cover2;
m_cover_ptr[2] = (cover_type)cover3;
if(x == m_last_x+1 && m_cur_span->len > 0)
{
m_cur_span->len += 3;
}
else
{
m_cur_span++;
m_cur_span->covers = m_cover_ptr;
m_cur_span->x = (int16)x;
m_cur_span->len = 3;
}
m_last_x = x;
m_cover_ptr += 3;
}
//--------------------------------------------------------------------
void add_cells(int x, unsigned len, const cover_type* covers)
{
memcpy(m_cover_ptr, covers, 3 * len * sizeof(cover_type));
if(x == m_last_x+1 && m_cur_span->len > 0)
{
m_cur_span->len += 3 * (int16)len;
}
else
{
m_cur_span++;
m_cur_span->covers = m_cover_ptr;
m_cur_span->x = (int16)x;
m_cur_span->len = 3 * (int16)len;
}
m_cover_ptr += 3 * len;
m_last_x = x + len - 1;
}
//--------------------------------------------------------------------
void add_span(int x, unsigned len, unsigned cover)
{
if(x == m_last_x+1 &&
m_cur_span->len < 0 &&
cover == *m_cur_span->covers)
{
m_cur_span->len -= 3 * (int16)len;
}
else
{
*m_cover_ptr = (cover_type)cover;
m_cur_span++;
m_cur_span->covers = m_cover_ptr;
m_cover_ptr += 3;
m_cur_span->x = (int16)x;
m_cur_span->len = 3 * (int16)(-int(len));
}
m_last_x = x + len - 1;
}
//--------------------------------------------------------------------
void finalize(int y)
{
m_y = y;
}
//--------------------------------------------------------------------
void reset_spans()
{
m_last_x = 0x7FFFFFF0;
m_cover_ptr = &m_covers[0];
m_cur_span = &m_spans[0];
m_cur_span->len = 0;
}
//--------------------------------------------------------------------
int y() const { return m_y; }
unsigned num_spans() const { return unsigned(m_cur_span - &m_spans[0]); }
const_iterator begin() const { return &m_spans[1]; }
private:
scanline_p8_subpix(const self_type&);
const self_type& operator = (const self_type&);
int m_last_x;
int m_y;
pod_array<cover_type> m_covers;
cover_type* m_cover_ptr;
pod_array<span> m_spans;
span* m_cur_span;
};
}
#endif

View File

@ -0,0 +1,195 @@
/*
* Copyright 2008, Andrej Spielmann <andrej.spielmann@seh.ox.ac.uk>.
* Copyright 2008, Stephan Aßmus <superstippi@gmx.de>.
* All rights reserved. Distributed under the terms of the MIT License.
*
* Copyright 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
*
*
* Class scanline_p8_subpix_avrg_filtering, a slightly modified version of
* scanline_p8 customized to store 3 covers per pixel and to implement
* average-based color filtering
*
*/
#ifndef AGG_SCANLINE_P_SUBPIX_AVRG_FILTERING_INCLUDED
#define AGG_SCANLINE_P_SUBPIX_AVRG_FILTERING_INCLUDED
#include "GlobalSubpixelSettings.h"
namespace agg
{
//========================================scanline_p8_subpix_avrg_filtering
//
// This is a general purpose scaline container which supports the interface
// used in the rasterizer::render(). See description of scanline_u8
// for details.
//
//------------------------------------------------------------------------
class scanline_p8_subpix_avrg_filtering
{
public:
typedef scanline_p8_subpix self_type;
typedef int8u cover_type;
typedef int16 coord_type;
//--------------------------------------------------------------------
struct span
{
coord_type x;
coord_type len; // If negative, it's a solid span, covers is valid
const cover_type* covers;
};
typedef span* iterator;
typedef const span* const_iterator;
scanline_p8_subpix_avrg_filtering() :
m_last_x(0x7FFFFFF0),
m_covers(),
m_cover_ptr(0),
m_spans(),
m_cur_span(0)
{
}
//--------------------------------------------------------------------
void reset(int min_x, int max_x)
{
unsigned max_len = 3*(max_x - min_x + 3);
if(max_len > m_spans.size())
{
m_spans.resize(max_len);
m_covers.resize(max_len);
}
m_last_x = 0x7FFFFFF0;
m_cover_ptr = &m_covers[0];
m_cur_span = &m_spans[0];
m_cur_span->len = 0;
}
//--------------------------------------------------------------------
void add_cell(int x, unsigned cover1, unsigned cover2, unsigned cover3)
{
// NOTE stippi: My basic idea is that filtering tries to minimize colored
// edges, but it does so by blurring the coverage values. This will also
// affect neighboring pixels and add blur where there were perfectly sharp
// edges. Andrej's method of filtering adds a special case for perfectly
// sharp edges, but the drawback here is that there will be a visible
// transition between blurred and non-blurred subpixels. I had the idea that
// when simply fading the subpixels towards the plain gray-scale-aa values,
// there must be a sweet spot for when colored edges become non-disturbing
// and there is still a benefit of sharpness compared to straight gray-scale-
// aa. The define above enables this method against the colored edges. My
// method still has a drawback, since jaggies in diagonal lines will be more
// visible again than with the filter method.
unsigned char averageWeight = gSubpixelAverageWeight;
unsigned char subpixelWeight = 255 - averageWeight;
unsigned int coverR;
unsigned int coverG;
unsigned int coverB;
unsigned int average = (cover1 + cover2 + cover3 + 2) / 3;
coverR = (cover1 * subpixelWeight + average * averageWeight) >> 8;
coverG = (cover2 * subpixelWeight + average * averageWeight) >> 8;
coverB = (cover3 * subpixelWeight + average * averageWeight) >> 8;
m_cover_ptr[0] = (cover_type)coverR;
m_cover_ptr[1] = (cover_type)coverG;
m_cover_ptr[2] = (cover_type)coverB;
if(x == m_last_x+1 && m_cur_span->len > 0)
{
m_cur_span->len += 3;
}
else
{
m_cur_span++;
m_cur_span->covers = m_cover_ptr;
m_cur_span->x = (int16)x;
m_cur_span->len = 3;
}
m_last_x = x;
m_cover_ptr += 3;
}
//--------------------------------------------------------------------
void add_cells(int x, unsigned len, const cover_type* covers)
{
memcpy(m_cover_ptr, covers, 3 * len * sizeof(cover_type));
if(x == m_last_x+1 && m_cur_span->len > 0)
{
m_cur_span->len += 3 * (int16)len;
}
else
{
m_cur_span++;
m_cur_span->covers = m_cover_ptr;
m_cur_span->x = (int16)x;
m_cur_span->len = 3 * (int16)len;
}
m_cover_ptr += 3 * len;
m_last_x = x + len - 1;
}
//--------------------------------------------------------------------
void add_span(int x, unsigned len, unsigned cover)
{
if(x == m_last_x+1 &&
m_cur_span->len < 0 &&
cover == *m_cur_span->covers)
{
m_cur_span->len -= 3 * (int16)len;
}
else
{
*m_cover_ptr = (cover_type)cover;
m_cur_span++;
m_cur_span->covers = m_cover_ptr;
m_cover_ptr += 3;
m_cur_span->x = (int16)x;
m_cur_span->len = 3 * (int16)(-int(len));
}
m_last_x = x + len - 1;
}
//--------------------------------------------------------------------
void finalize(int y)
{
m_y = y;
}
//--------------------------------------------------------------------
void reset_spans()
{
m_last_x = 0x7FFFFFF0;
m_cover_ptr = &m_covers[0];
m_cur_span = &m_spans[0];
m_cur_span->len = 0;
}
//--------------------------------------------------------------------
int y() const { return m_y; }
unsigned num_spans() const { return unsigned(m_cur_span - &m_spans[0]); }
const_iterator begin() const { return &m_spans[1]; }
private:
scanline_p8_subpix_avrg_filtering(const self_type&);
const self_type& operator = (const self_type&);
int m_last_x;
int m_y;
pod_array<cover_type> m_covers;
cover_type* m_cover_ptr;
pod_array<span> m_spans;
span* m_cur_span;
};
}
#endif

View File

@ -0,0 +1,165 @@
/*
* Copyright 2008, Andrej Spielmann <andrej.spielmann@seh.ox.ac.uk>.
* Copyright 2008, Stephan Aßmus <superstippi@gmx.de>.
* All rights reserved. Distributed under the terms of the MIT License.
*
* Copyright 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
*
*
* Class scanline_u8_subpix_avrg_filtering, a slightly modified version of
* scanline_u8 customized to store 3 covers per pixel and to implement
* average-based color filtering
*
*/
#ifndef AGG_SCANLINE_U_SUBPIX_AVRG_FILTERING_INCLUDED
#define AGG_SCANLINE_U_SUBPIX_AVRG_FILTERING_INCLUDED
#include "GlobalSubpixelSettings.h"
namespace agg
{
//=======================================scanline_u8_subpix_avrg_filtering
//------------------------------------------------------------------------
class scanline_u8_subpix_avrg_filtering
{
public:
typedef scanline_u8_subpix_avrg_filtering self_type;
typedef int8u cover_type;
typedef int16 coord_type;
//--------------------------------------------------------------------
struct span
{
coord_type x;
coord_type len;
cover_type* covers;
};
typedef span* iterator;
typedef const span* const_iterator;
//--------------------------------------------------------------------
scanline_u8_subpix_avrg_filtering() :
m_min_x(0),
m_last_x(0x7FFFFFF0),
m_cur_span(0)
{}
//--------------------------------------------------------------------
void reset(int min_x, int max_x)
{
unsigned max_len = 3*(max_x - min_x + 2);
if(max_len > m_spans.size())
{
m_spans.resize(max_len);
m_covers.resize(max_len);
}
m_last_x = 0x7FFFFFF0;
m_min_x = min_x;
m_cur_span = &m_spans[0];
}
//--------------------------------------------------------------------
void add_cell(int x, unsigned cover1, unsigned cover2, unsigned cover3)
{
// NOTE stippi: My basic idea is that filtering tries to minimize colored
// edges, but it does so by blurring the coverage values. This will also
// affect neighboring pixels and add blur where there were perfectly sharp
// edges. Andrej's method of filtering adds a special case for perfectly
// sharp edges, but the drawback here is that there will be a visible
// transition between blurred and non-blurred subpixels. I had the idea that
// when simply fading the subpixels towards the plain gray-scale-aa values,
// there must be a sweet spot for when colored edges become non-disturbing
// and there is still a benefit of sharpness compared to straight gray-scale-
// aa. The define above enables this method against the colored edges. My
// method still has a drawback, since jaggies in diagonal lines will be more
// visible again than with the filter method.
unsigned char averageWeight = gSubpixelAverageWeight;
unsigned char subpixelWeight = 255 - averageWeight;
unsigned int coverR;
unsigned int coverG;
unsigned int coverB;
unsigned int average = (cover1 + cover2 + cover3 + 2) / 3;
coverR = (cover1 * subpixelWeight + average * averageWeight) >> 8;
coverG = (cover2 * subpixelWeight + average * averageWeight) >> 8;
coverB = (cover3 * subpixelWeight + average * averageWeight) >> 8;
x -= m_min_x;
m_covers[3 * x] = (cover_type)coverR;
m_covers[3 * x + 1] = (cover_type)coverG;
m_covers[3 * x + 2] = (cover_type)coverB;
if(x == m_last_x + 1)
{
m_cur_span->len += 3;
}
else
{
m_cur_span++;
m_cur_span->x = (coord_type)(x + m_min_x);
m_cur_span->len = 3;
m_cur_span->covers = &m_covers[3 * x];
}
m_last_x = x;
}
//--------------------------------------------------------------------
void add_span(int x, unsigned len, unsigned cover)
{
x -= m_min_x;
memset(&m_covers[3 * x], cover, 3 * len);
if(x == m_last_x+1)
{
m_cur_span->len += 3 * (coord_type)len;
}
else
{
m_cur_span++;
m_cur_span->x = (coord_type)(x + m_min_x);
m_cur_span->len = 3 * (coord_type)len;
m_cur_span->covers = &m_covers[3 * x];
}
m_last_x = x + len - 1;
}
//--------------------------------------------------------------------
void finalize(int y)
{
m_y = y;
}
//--------------------------------------------------------------------
void reset_spans()
{
m_last_x = 0x7FFFFFF0;
m_cur_span = &m_spans[0];
}
//--------------------------------------------------------------------
int y() const { return m_y; }
unsigned num_spans() const { return unsigned(m_cur_span - &m_spans[0]); }
const_iterator begin() const { return &m_spans[1]; }
iterator begin() { return &m_spans[1]; }
private:
scanline_u8_subpix_avrg_filtering(const self_type&);
const self_type& operator = (const self_type&);
private:
int m_min_x;
int m_last_x;
int m_y;
pod_array<cover_type> m_covers;
pod_array<span> m_spans;
span* m_cur_span;
};
}
#endif

View File

@ -22,11 +22,18 @@
#include <agg_scanline_u.h>
#include <agg_rendering_buffer.h>
#include "agg_rasterizer_scanline_aa_subpix.h"
#include "agg_renderer_region.h"
#include "agg_renderer_scanline_subpix.h"
#include "agg_scanline_p_subpix.h"
#include "agg_scanline_p_subpix_avrg_filtering.h"
#include "agg_scanline_u_subpix.h"
#include "agg_scanline_u_subpix_avrg_filtering.h"
#include "GlobalSubpixelSettings.h"
#include "PixelFormat.h"
#define ALIASED_DRAWING 0
typedef PixelFormat pixfmt;
@ -45,13 +52,21 @@
typedef agg::scanline_u8 scanline_unpacked_type;
typedef agg::scanline_p8 scanline_packed_type;
typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_type;
#ifdef AVERAGE_BASED_SUBPIXEL_FILTERING
typedef agg::scanline_p8_subpix_avrg_filtering scanline_packed_subpix_type;
typedef agg::scanline_u8_subpix_avrg_filtering scanline_unpacked_subpix_type;
#else
typedef agg::scanline_p8_subpix scanline_packed_subpix_type;
typedef agg::scanline_u8_subpix scanline_unpacked_subpix_type;
#endif
typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_type;
#endif // !ALIASED_DRAWING
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;
typedef agg::rasterizer_scanline_aa_subpix<> rasterizer_subpix_type;
#endif // DEFINES_H

View File

@ -11,7 +11,7 @@
#define DRAWING_MODE_ADD_SUBPIX_H
#include "DrawingMode.h"
#include "GlobalSubpixelSettings.h"
// BLEND_ADD_SUBPIX
#define BLEND_ADD_SUBPIX(d, r, g, b, a1, a2, a3) \
@ -25,70 +25,19 @@
}
// BLEND_ADD
#define BLEND_ADD(d, r, g, b, a) \
{ \
pixel32 _p; \
_p.data32 = *(uint32*)d; \
uint8 rt = min_c(255, _p.data8[2] + (r)); \
uint8 gt = min_c(255, _p.data8[1] + (g)); \
uint8 bt = min_c(255, _p.data8[0] + (b)); \
BLEND(d, rt, gt, bt, a); \
}
//ASSIGN_ADD
#define ASSIGN_ADD(d, r, g, b) \
{ \
pixel32 _p; \
_p.data32 = *(uint32*)d; \
d[0] = min_c(255, _p.data8[0] + (b)); \
d[1] = min_c(255, _p.data8[1] + (g)); \
d[2] = min_c(255, _p.data8[2] + (r)); \
d[3] = 255; \
}
// blend_hline_add_subpix
void
blend_hline_add_subpix(int x, int y, unsigned len, const color_type& c,
uint8 cover, agg_buffer* buffer, const PatternHandler* pattern)
{
uint8* p = buffer->row_ptr(y) + (x << 2);
if (cover == 255) {
do {
rgb_color color = pattern->ColorAt(x, y);
ASSIGN_ADD(p, color.red, color.green, color.blue);
p += 4;
x++;
len -= 3;
} while (len);
} else {
do {
rgb_color color = pattern->ColorAt(x, y);
BLEND_ADD(p, color.red, color.green, color.blue, cover);
x++;
p += 4;
len -= 3;
} while (len);
}
}
// blend_solid_hspan_add_subpix
void
blend_solid_hspan_add_subpix(int x, int y, unsigned len, const color_type& c,
const uint8* covers, agg_buffer* buffer, const PatternHandler* pattern)
{
const int subpixelL = gSubpixelOrderingRGB ? 2 : 0;
const int subpixelM = 1;
const int subpixelR = gSubpixelOrderingRGB ? 0 : 2;
uint8* p = buffer->row_ptr(y) + (x << 2);
do {
rgb_color color = pattern->ColorAt(x, y);
BLEND_ADD_SUBPIX(p, color.red, color.green, color.blue,
covers[2], covers[1], covers[0]);
covers[subpixelL], covers[subpixelM], covers[subpixelR]);
covers += 3;
p += 4;
x++;

View File

@ -11,6 +11,7 @@
#define DRAWING_MODE_ALPHA_CC_SUBPIX_H
#include "DrawingMode.h"
#include "GlobalSubpixelSettings.h"
// BLEND_ALPHA_CC_SUBPIX
#define BLEND_ALPHA_CC_SUBPIX(d, r, g, b, a1, a2, a3) \
@ -19,71 +20,6 @@
}
// BLEND_ALPHA_CC
#define BLEND_ALPHA_CC(d, r, g, b, a) \
{ \
BLEND_COMPOSITE16(d, r, g, b, a); \
}
// ASSIGN_ALPHA_CC
#define ASSIGN_ALPHA_CC(d, r, g, b) \
{ \
d[0] = (b); \
d[1] = (g); \
d[2] = (r); \
d[3] = 255; \
}
// blend_hline_alpha_cc_subpix
void
blend_hline_alpha_cc_subpix(int x, int y, unsigned len, const color_type& c,
uint8 cover, agg_buffer* buffer, const PatternHandler* pattern)
{
rgb_color color = pattern->HighColor();
uint16 alpha = color.alpha * cover;
if (alpha == 255 * 255) {
// cache the low and high color as 32bit values
// high color
uint32 vh;
uint8* p8 = (uint8*)&vh;
p8[0] = color.blue;
p8[1] = color.green;
p8[2] = color.red;
p8[3] = 255;
// low color
color = pattern->LowColor();
uint32 vl;
p8 = (uint8*)&vl;
p8[0] = color.blue;
p8[1] = color.green;
p8[2] = color.red;
p8[3] = 255;
// row offset as 32 bit pointer
uint32* p32 = (uint32*)(buffer->row_ptr(y)) + x;
do {
if (pattern->IsHighColor(x, y))
*p32 = vh;
else
*p32 = vl;
p32++;
x++;
len -= 3;
} while (len);
} else {
uint8* p = buffer->row_ptr(y) + (x << 2);
do {
rgb_color color = pattern->ColorAt(x, y);
BLEND_ALPHA_CC(p, color.red, color.green, color.blue, alpha);
x++;
p += 4;
len -= 3;
} while (len);
}
}
// blend_solid_hspan_alpha_cc_subpix
void
blend_solid_hspan_alpha_cc_subpix(int x, int y, unsigned len,
@ -95,13 +31,16 @@ blend_solid_hspan_alpha_cc_subpix(int x, int y, unsigned len,
uint16 alphaRed;
uint16 alphaGreen;
uint16 alphaBlue;
const int subpixelL = gSubpixelOrderingRGB ? 2 : 0;
const int subpixelM = 1;
const int subpixelR = gSubpixelOrderingRGB ? 0 : 2;
do {
alphaRed = hAlpha * covers[0];
alphaGreen = hAlpha * covers[1];
alphaBlue = hAlpha * covers[2];
alphaRed = hAlpha * covers[subpixelL];
alphaGreen = hAlpha * covers[subpixelM];
alphaBlue = hAlpha * covers[subpixelR];
rgb_color color = pattern->ColorAt(x, y);
BLEND_ALPHA_CC_SUBPIX(p, color.red, color.green, color.blue,
alphaBlue,alphaGreen, alphaRed);
alphaBlue, alphaGreen, alphaRed);
covers += 3;
p += 4;
x++;

View File

@ -11,6 +11,7 @@
#define DRAWING_MODE_ALPHA_CO_SUBPIX_H
#include "DrawingMode.h"
#include "GlobalSubpixelSettings.h"
// BLEND_ALPHA_CO_SUBPIX
#define BLEND_ALPHA_CO_SUBPIX(d, r, g, b, a1, a2, a3) \
@ -19,71 +20,6 @@
}
// BLEND_ALPHA_CO
#define BLEND_ALPHA_CO(d, r, g, b, a) \
{ \
BLEND16(d, r, g, b, a); \
}
// ASSIGN_ALPHA_CO
#define ASSIGN_ALPHA_CO(d, r, g, b) \
{ \
d[0] = (b); \
d[1] = (g); \
d[2] = (r); \
d[3] = 255; \
}
// blend_hline_alpha_co_subpix
void
blend_hline_alpha_co_subpix(int x, int y, unsigned len, const color_type& c,
uint8 cover, agg_buffer* buffer, const PatternHandler* pattern)
{
rgb_color color = pattern->HighColor();
uint16 alpha = color.alpha * cover;
if (alpha == 255 * 255) {
// cache the low and high color as 32bit values
// high color
uint32 vh;
uint8* p8 = (uint8*)&vh;
p8[0] = color.blue;
p8[1] = color.green;
p8[2] = color.red;
p8[3] = 255;
// low color
color = pattern->LowColor();
uint32 vl;
p8 = (uint8*)&vl;
p8[0] = color.blue;
p8[1] = color.green;
p8[2] = color.red;
p8[3] = 255;
// row offset as 32bit pointer
uint32* p32 = (uint32*)(buffer->row_ptr(y)) + x;
do {
if (pattern->IsHighColor(x, y))
*p32 = vh;
else
*p32 = vl;
p32++;
x++;
len -= 3;
} while (len);
} else {
uint8* p = buffer->row_ptr(y) + (x << 2);
do {
rgb_color color = pattern->ColorAt(x, y);
BLEND_ALPHA_CO(p, color.red, color.green, color.blue, alpha);
x++;
p += 4;
len -= 3;
} while (len);
}
}
// blend_solid_hspan_alpha_co_subpix
void
blend_solid_hspan_alpha_co_subpix(int x, int y, unsigned len,
@ -95,10 +31,13 @@ blend_solid_hspan_alpha_co_subpix(int x, int y, unsigned len,
uint16 alphaRed;
uint16 alphaGreen;
uint16 alphaBlue;
const int subpixelL = gSubpixelOrderingRGB ? 2 : 0;
const int subpixelM = 1;
const int subpixelR = gSubpixelOrderingRGB ? 0 : 2;
do {
alphaRed = hAlpha * covers[0];
alphaGreen = hAlpha * covers[1];
alphaBlue = hAlpha * covers[2];
alphaRed = hAlpha * covers[subpixelL];
alphaGreen = hAlpha * covers[subpixelM];
alphaBlue = hAlpha * covers[subpixelR];
rgb_color color = pattern->ColorAt(x, y);
BLEND_ALPHA_CO_SUBPIX(p, color.red, color.green, color.blue,
alphaBlue, alphaGreen, alphaRed);

View File

@ -11,45 +11,7 @@
#define DRAWING_MODE_ALPHA_CO_SOLID_SUBPIX_H
#include "DrawingModeAlphaCOSUBPIX.h"
// blend_hline_alpha_co_solid_subpix
void
blend_hline_alpha_co_solid_subpix(int x, int y, unsigned len,
const color_type& c, uint8 cover, agg_buffer* buffer,
const PatternHandler* pattern)
{
uint16 alpha = pattern->HighColor().alpha * cover;
if (alpha == 255 * 255) {
// cache the color as 32bit values
uint32 v;
uint8* p8 = (uint8*)&v;
p8[0] = c.b;
p8[1] = c.g;
p8[2] = c.r;
p8[3] = 255;
// row offset as 32bit pointer
uint32* p32 = (uint32*)(buffer->row_ptr(y)) + x;
do {
*p32 = v;
p32++;
x++;
len -= 3;
} while (len);
} else {
uint8* p = buffer->row_ptr(y) + (x << 2);
if (len < 12) {
do {
BLEND_ALPHA_CO(p, c.r, c.g, c.b, alpha);
x++;
p += 4;
len -= 3;
} while (len);
} else {
alpha = alpha >> 8;
blend_line32(p, len / 3, c.r, c.g, c.b, alpha);
}
}
}
#include "GlobalSubpixelSettings.h"
// blend_solid_hspan_alpha_co_solid_subpix
@ -63,10 +25,13 @@ blend_solid_hspan_alpha_co_solid_subpix(int x, int y, unsigned len,
uint16 alphaRed;
uint16 alphaGreen;
uint16 alphaBlue;
const int subpixelL = gSubpixelOrderingRGB ? 2 : 0;
const int subpixelM = 1;
const int subpixelR = gSubpixelOrderingRGB ? 0 : 2;
do {
alphaRed = hAlpha * covers[0];
alphaGreen = hAlpha * covers[1];
alphaBlue = hAlpha * covers[2];
alphaRed = hAlpha * covers[subpixelL];
alphaGreen = hAlpha * covers[subpixelM];
alphaBlue = hAlpha * covers[subpixelR];
BLEND_ALPHA_CO_SUBPIX(p, c.r, c.g, c.b,
alphaBlue, alphaGreen, alphaRed);
covers += 3;

View File

@ -11,6 +11,7 @@
#define DRAWING_MODE_ALPHA_PC_SUBPIX_H
#include "DrawingMode.h"
#include "GlobalSubpixelSettings.h"
// BLEND_ALPHA_PC_SUBPIX
#define BLEND_ALPHA_PC_SUBPIX(d, r, g, b, a1, a2, a3) \
@ -19,46 +20,6 @@
}
// BLEND_ALPHA_PC
#define BLEND_ALPHA_PC(d, r, g, b, a) \
{ \
BLEND_COMPOSITE16(d, r, g, b, a); \
}
// ASSIGN_ALPHA_PC
#define ASSIGN_ALPHA_PC(d, r, g, b) \
{ \
d[0] = (b); \
d[1] = (g); \
d[2] = (r); \
d[3] = 255; \
}
// blend_hline_alpha_pc_subpix
void
blend_hline_alpha_pc_subpix(int x, int y, unsigned len, const color_type& c,
uint8 cover, agg_buffer* buffer, const PatternHandler* pattern)
{
uint8* p = buffer->row_ptr(y) + (x << 2);
do {
rgb_color color = pattern->ColorAt(x, y);
uint16 alpha = color.alpha * cover;
if (alpha) {
if (alpha == 255) {
ASSIGN_ALPHA_PC(p, color.red, color.green, color.blue);
} else {
BLEND_ALPHA_PC(p, color.red, color.green, color.blue, alpha);
}
}
x++;
p += 4;
len -= 3;
} while (len);
}
// blend_solid_hspan_alpha_pc_subpix
void
blend_solid_hspan_alpha_pc_subpix(int x, int y, unsigned len,
@ -69,11 +30,14 @@ blend_solid_hspan_alpha_pc_subpix(int x, int y, unsigned len,
uint16 alphaRed;
uint16 alphaGreen;
uint16 alphaBlue;
const int subpixelL = gSubpixelOrderingRGB ? 2 : 0;
const int subpixelM = 1;
const int subpixelR = gSubpixelOrderingRGB ? 0 : 2;
do {
rgb_color color = pattern->ColorAt(x, y);
alphaRed = color.alpha * covers[0];
alphaGreen = color.alpha * covers[1];
alphaBlue = color.alpha * covers[2];
alphaRed = color.alpha * covers[subpixelL];
alphaGreen = color.alpha * covers[subpixelM];
alphaBlue = color.alpha * covers[subpixelR];
BLEND_ALPHA_PC_SUBPIX(p, color.red, color.green, color.blue,
alphaBlue, alphaGreen, alphaRed);
covers += 3;

View File

@ -11,6 +11,7 @@
#define DRAWING_MODE_ALPHA_PO_SUBPIX_H
#include "DrawingMode.h"
#include "GlobalSubpixelSettings.h"
// BLEND_ALPHA_PO_SUBPIX
#define BLEND_ALPHA_PO_SUBPIX(d, r, g, b, a1, a2, a3) \
@ -18,44 +19,6 @@
BLEND16_SUBPIX(d, r, g, b, a1, a2, a3); \
}
// BLEND_ALPHA_PO
#define BLEND_ALPHA_PO(d, r, g, b, a) \
{ \
BLEND16(d, r, g, b, a); \
}
// ASSIGN_ALPHA_PO
#define ASSIGN_ALPHA_PO(d, r, g, b) \
{ \
d[0] = (b); \
d[1] = (g); \
d[2] = (r); \
d[3] = 255; \
}
// blend_hline_alpha_po_subpix
void
blend_hline_alpha_po_subpix(int x, int y, unsigned len, const color_type& c,
uint8 cover, agg_buffer* buffer, const PatternHandler* pattern)
{
uint8* p = buffer->row_ptr(y) + (x << 2);
do {
rgb_color color = pattern->ColorAt(x, y);
uint16 alpha = color.alpha * cover;
if (alpha) {
if (alpha == 255) {
ASSIGN_ALPHA_PO(p, color.red, color.green, color.blue);
} else {
BLEND_ALPHA_PO(p, color.red, color.green, color.blue, alpha);
}
}
x++;
p += 4;
len -= 3;
} while(len);
}
// blend_solid_hspan_alpha_po_subpix
void
@ -67,11 +30,14 @@ blend_solid_hspan_alpha_po_subpix(int x, int y, unsigned len,
uint16 alphaRed;
uint16 alphaGreen;
uint16 alphaBlue;
const int subpixelL = gSubpixelOrderingRGB ? 2 : 0;
const int subpixelM = 1;
const int subpixelR = gSubpixelOrderingRGB ? 0 : 2;
do {
rgb_color color = pattern->ColorAt(x, y);
alphaRed = color.alpha * covers[0];
alphaGreen = color.alpha * covers[1];
alphaBlue = color.alpha * covers[2];
alphaRed = color.alpha * covers[subpixelL];
alphaGreen = color.alpha * covers[subpixelM];
alphaBlue = color.alpha * covers[subpixelR];
BLEND_ALPHA_PO_SUBPIX(p, color.red, color.green, color.blue,
alphaBlue, alphaGreen, alphaRed);
covers += 3;

View File

@ -11,46 +11,7 @@
#define DRAWING_MODE_ALPHA_PO_SOLID_SUBPIX_H
#include "DrawingModeAlphaPOSUBPIX.h"
// blend_hline_alpha_po_solid_subpix
void
blend_hline_alpha_po_solid_subpix(int x, int y, unsigned len,
const color_type& c, uint8 cover, agg_buffer* buffer,
const PatternHandler* pattern)
{
uint16 alpha = c.a * cover;
if (alpha == 255 * 255) {
// cache the color as 32bit values
uint32 v;
uint8* p8 = (uint8*)&v;
p8[0] = c.b;
p8[1] = c.g;
p8[2] = c.r;
p8[3] = 255;
// row offset as 32bit pointer
uint32* p32 = (uint32*)(buffer->row_ptr(y)) + x;
do {
*p32 = v;
p32++;
x++;
len -= 3;
} while (len);
} else {
uint8* p = buffer->row_ptr(y) + (x << 2);
if (len < 12) {
do {
BLEND_ALPHA_CO(p, c.r, c.g, c.b, alpha);
x++;
p += 4;
len -= 3;
} while (len);
} else {
alpha = alpha >> 8;
blend_line32(p, len / 3, c.r, c.g, c.b, alpha);
}
}
}
#include "GlobalSubpixelSettings.h"
// blend_solid_hspan_alpha_po_solid_subpix
void
@ -62,10 +23,13 @@ blend_solid_hspan_alpha_po_solid_subpix(int x, int y, unsigned len,
uint16 alphaRed;
uint16 alphaGreen;
uint16 alphaBlue;
const int subpixelL = gSubpixelOrderingRGB ? 2 : 0;
const int subpixelM = 1;
const int subpixelR = gSubpixelOrderingRGB ? 0 : 2;
do {
alphaRed = c.a * covers[0];
alphaGreen = c.a * covers[1];
alphaBlue = c.a * covers[2];
alphaRed = c.a * covers[subpixelL];
alphaGreen = c.a * covers[subpixelM];
alphaBlue = c.a * covers[subpixelR];
BLEND_ALPHA_PO_SUBPIX(p, c.r, c.g, c.b,
alphaBlue, alphaGreen, alphaRed);
covers += 3;

View File

@ -11,6 +11,7 @@
#define DRAWING_MODE_BLEND_SUBPIX_H
#include "DrawingMode.h"
#include "GlobalSubpixelSettings.h"
// BLEND_BLEND_SUBPIX
@ -25,70 +26,19 @@
}
// BLEND_BLEND
#define BLEND_BLEND(d, r, g, b, a) \
{ \
pixel32 _p; \
_p.data32 = *(uint32*)d; \
uint8 bt = (_p.data8[0] + (b)) >> 1; \
uint8 gt = (_p.data8[1] + (g)) >> 1; \
uint8 rt = (_p.data8[2] + (r)) >> 1; \
BLEND(d, rt, gt, bt, a); \
}
// ASSIGN_BLEND
#define ASSIGN_BLEND(d, r, g, b) \
{ \
pixel32 _p; \
_p.data32 = *(uint32*)d; \
d[0] = (_p.data8[0] + (b)) >> 1; \
d[1] = (_p.data8[1] + (g)) >> 1; \
d[2] = (_p.data8[2] + (r)) >> 1; \
d[3] = 255; \
}
// blend_hline_blend_subpix
void
blend_hline_blend_subpix(int x, int y, unsigned len, const color_type& c,
uint8 cover, agg_buffer* buffer, const PatternHandler* pattern)
{
uint8* p = buffer->row_ptr(y) + (x << 2);
if (cover == 255) {
do {
rgb_color color = pattern->ColorAt(x, y);
ASSIGN_BLEND(p, color.red, color.green, color.blue);
p += 4;
x++;
len -= 3;
} while (len);
} else {
do {
rgb_color color = pattern->ColorAt(x, y);
BLEND_BLEND(p, color.red, color.green, color.blue, cover);
p += 4;
x++;
len -= 3;
} while (len);
}
}
// blend_solid_hspan_blend_subpix
void
blend_solid_hspan_blend_subpix(int x, int y, unsigned len, const color_type& c,
const uint8* covers, agg_buffer* buffer, const PatternHandler* pattern)
{
uint8* p = buffer->row_ptr(y) + (x << 2);
const int subpixelL = gSubpixelOrderingRGB ? 2 : 0;
const int subpixelM = 1;
const int subpixelR = gSubpixelOrderingRGB ? 0 : 2;
do {
rgb_color color = pattern->ColorAt(x, y);
BLEND_BLEND_SUBPIX(p, color.red, color.green, color.blue,
covers[2], covers[1], covers[0]);
covers[subpixelL], covers[subpixelM], covers[subpixelR]);
covers += 3;
p += 4;
x++;

View File

@ -11,6 +11,7 @@
#define DRAWING_MODE_COPY_SUBPIX_H
#include "DrawingMode.h"
#include "GlobalSubpixelSettings.h"
// BLEND_COPY_SUBPIX
#define BLEND_COPY_SUBPIX(d, r2, g2, b2, a1, a2, a3, r1, g1, b1) \
@ -19,72 +20,6 @@
}
// BLEND_COPY
#define BLEND_COPY(d, r2, g2, b2, a, r1, g1, b1) \
{ \
BLEND_FROM(d, r1, g1, b1, r2, g2, b2, a); \
}
// ASSIGN_COPY
#define ASSIGN_COPY(d, r, g, b, a) \
{ \
d[0] = (b); \
d[1] = (g); \
d[2] = (r); \
d[3] = (a); \
}
// blend_hline_copy_subpix
void
blend_hline_copy_subpix(int x, int y, unsigned len, const color_type& c,
uint8 cover, agg_buffer* buffer, const PatternHandler* pattern)
{
if (cover == 255) {
// cache the low and high color as 32bit values
// high color
rgb_color color = pattern->HighColor();
uint32 vh;
uint8* p8 = (uint8*)&vh;
p8[0] = (uint8)color.blue;
p8[1] = (uint8)color.green;
p8[2] = (uint8)color.red;
p8[3] = 255;
// low color
color = pattern->LowColor();
uint32 vl;
p8 = (uint8*)&vl;
p8[0] = (uint8)color.blue;
p8[1] = (uint8)color.green;
p8[2] = (uint8)color.red;
p8[3] = 255;
// row offset as 32bit pointer
uint32* p32 = (uint32*)(buffer->row_ptr(y)) + x;
do {
if (pattern->IsHighColor(x, y))
*p32 = vh;
else
*p32 = vl;
p32++;
x++;
len -= 3;
} while (len);
} else {
uint8* p = buffer->row_ptr(y) + (x << 2);
rgb_color l = pattern->LowColor();
do {
rgb_color color = pattern->ColorAt(x, y);
BLEND_COPY(p, color.red, color.green, color.blue, cover,
l.red, l.green, l.blue);
x++;
p += 4;
len -= 3;
} while (len);
}
}
// blend_solid_hspan_copy_subpix
void
blend_solid_hspan_copy_subpix(int x, int y, unsigned len, const color_type& c,
@ -92,10 +27,14 @@ blend_solid_hspan_copy_subpix(int x, int y, unsigned len, const color_type& c,
{
uint8* p = buffer->row_ptr(y) + (x << 2);
rgb_color l = pattern->LowColor();
const int subpixelL = gSubpixelOrderingRGB ? 2 : 0;
const int subpixelM = 1;
const int subpixelR = gSubpixelOrderingRGB ? 0 : 2;
do {
rgb_color color = pattern->ColorAt(x, y);
BLEND_COPY_SUBPIX(p, color.red, color.green, color.blue,
covers[2], covers[1], covers[0], l.red, l.green, l.blue);
covers[subpixelL], covers[subpixelM], covers[subpixelR], l.red,
l.green, l.blue);
covers += 3;
p += 4;
x++;

View File

@ -11,36 +11,7 @@
#define DRAWING_MODE_COPY_SOLID_SUBPIX_H
#include "DrawingModeOverSUBPIX.h"
// blend_hline_copy_solid_subpix
void
blend_hline_copy_solid_subpix(int x, int y, unsigned len, const color_type& c,
uint8 cover, agg_buffer* buffer, const PatternHandler* pattern)
{
if (cover == 255) {
uint32 v;
uint8* p8 = (uint8*)&v;
p8[0] = (uint8)c.b;
p8[1] = (uint8)c.g;
p8[2] = (uint8)c.r;
p8[3] = 255;
uint32* p32 = (uint32*)(buffer->row_ptr(y)) + x;
do {
*p32 = v;
p32++;
x++;
len -= 3;
} while (len);
} else {
uint8* p = buffer->row_ptr(y) + (x << 2);
do {
BLEND_OVER(p, c.r, c.g, c.b, cover);
x++;
p += 4;
len -= 3;
} while (len);
}
}
#include "GlobalSubpixelSettings.h"
// blend_solid_hspan_copy_solid_subpix
@ -50,8 +21,12 @@ blend_solid_hspan_copy_solid_subpix(int x, int y, unsigned len,
const PatternHandler* pattern)
{
uint8* p = buffer->row_ptr(y) + (x << 2);
const int subpixelL = gSubpixelOrderingRGB ? 2 : 0;
const int subpixelM = 1;
const int subpixelR = gSubpixelOrderingRGB ? 0 : 2;
do {
BLEND_OVER_SUBPIX(p, c.r, c.g, c.b, covers[2], covers[1], covers[0]);
BLEND_OVER_SUBPIX(p, c.r, c.g, c.b, covers[subpixelL],
covers[subpixelM], covers[subpixelR]);
covers += 3;
p += 4;
x++;

View File

@ -11,38 +11,7 @@
#define DRAWING_MODE_COPY_TEXT_SUBPIX_H
#include "DrawingModeCopySUBPIX.h"
// blend_hline_copy_text_subpix
void
blend_hline_copy_text_subpix(int x, int y, unsigned len, const color_type& c,
uint8 cover, agg_buffer* buffer, const PatternHandler* pattern)
{
if (cover == 255) {
// cache the color as 32bit value
uint32 v;
uint8* p8 = (uint8*)&v;
p8[0] = (uint8)c.b;
p8[1] = (uint8)c.g;
p8[2] = (uint8)c.r;
p8[3] = 255;
// row offset as 32bit pointer
uint32* p32 = (uint32*)(buffer->row_ptr(y)) + x;
do {
*p32 = v;
p32++;
len -= 3;
} while(len);
} else {
uint8* p = buffer->row_ptr(y) + (x << 2);
rgb_color l = pattern->LowColor();
do {
BLEND_COPY(p, c.r, c.g, c.b, cover, l.red, l.green, l.blue);
p += 4;
len -= 3;
} while (len);
}
}
#include "GlobalSubpixelSettings.h"
// blend_solid_hspan_copy_text_subpix
void
@ -52,9 +21,13 @@ blend_solid_hspan_copy_text_subpix(int x, int y, unsigned len,
{
//printf("blend_solid_hspan_copy_text(%d, %d)\n", x, len);
uint8* p = buffer->row_ptr(y) + (x << 2);
//rgb_color l = pattern->LowColor();
rgb_color l = pattern->LowColor();
const int subpixelL = gSubpixelOrderingRGB ? 2 : 0;
const int subpixelM = 1;
const int subpixelR = gSubpixelOrderingRGB ? 0 : 2;
do {
BLEND_OVER_SUBPIX(p, c.r, c.g, c.b, covers[2], covers[1], covers[0]);
BLEND_COPY_SUBPIX(p, c.r, c.g, c.b, covers[subpixelL],
covers[subpixelM], covers[subpixelR], l.red, l.green, l.blue);
covers += 3;
p += 4;
x++;

View File

@ -11,6 +11,7 @@
#define DRAWING_MODE_ERASE_SUBPIX_H
#include "DrawingMode.h"
#include "GlobalSubpixelSettings.h"
// BLEND_ERASE_SUBPIX
#define BLEND_ERASE_SUBPIX(d, r, g, b, a1, a2, a3) \
@ -19,58 +20,6 @@
}
// BLEND_ERASE
#define BLEND_ERASE(d, r, g, b, a) \
{ \
BLEND(d, r, g, b, a); \
}
// ASSIGN_ERASE
#define ASSIGN_ERASE(d, r, g, b) \
{ \
d[0] = (b); \
d[1] = (g); \
d[2] = (r); \
d[3] = 255; \
}
// blend_hline_erase_subpix
void
blend_hline_erase_subpix(int x, int y, unsigned len, const color_type& c,
uint8 cover, agg_buffer* buffer, const PatternHandler* pattern)
{
if (cover == 255) {
rgb_color color = pattern->LowColor();
uint32 v;
uint8* p8 = (uint8*)&v;
p8[0] = (uint8)color.blue;
p8[1] = (uint8)color.green;
p8[2] = (uint8)color.red;
p8[3] = 255;
uint32* p32 = (uint32*)(buffer->row_ptr(y)) + x;
do {
if (pattern->IsHighColor(x, y))
*p32 = v;
p32++;
x +=3;
len -= 3;
} while (len);
} else {
uint8* p = buffer->row_ptr(y) + (x << 2);
rgb_color color = pattern->LowColor();
do {
if (pattern->IsHighColor(x, y))
BLEND_ERASE(p, color.red, color.green, color.blue, cover);
x++;
p += 4;
len -= 3;
} while (len);
}
}
// blend_solid_hspan_erase_subpix
void
blend_solid_hspan_erase_subpix(int x, int y, unsigned len, const color_type& c,
@ -78,10 +27,13 @@ blend_solid_hspan_erase_subpix(int x, int y, unsigned len, const color_type& c,
{
uint8* p = buffer->row_ptr(y) + (x << 2);
rgb_color color = pattern->LowColor();
const int subpixelL = gSubpixelOrderingRGB ? 2 : 0;
const int subpixelM = 1;
const int subpixelR = gSubpixelOrderingRGB ? 0 : 2;
do {
if (pattern->IsHighColor(x, y)) {
BLEND_ERASE_SUBPIX(p, color.red, color.green, color.blue,
covers[2], covers[1], covers[0]);
covers[subpixelL], covers[subpixelM], covers[subpixelR]);
}
covers += 3;
p += 4;

View File

@ -11,6 +11,7 @@
#define DRAWING_MODE_INVERT_SUBPIX_H
#include "DrawingMode.h"
#include "GlobalSubpixelSettings.h"
// BLEND_INVERT_SUBPIX
#define BLEND_INVERT_SUBPIX(d, a1, a2, a3) \
@ -22,64 +23,20 @@
}
// BLEND_INVERT
#define BLEND_INVERT(d, a) \
{ \
pixel32 _p; \
_p.data32 = *(uint32*)d; \
BLEND(d, 255 - _p.data8[2], 255 - _p.data8[1], 255 - _p.data8[0], a); \
}
// ASSIGN_INVERT
#define ASSIGN_INVERT(d) \
{ \
pixel32 _p; \
_p.data32 = *(uint32*)d; \
d[0] = 255 - _p.data8[0]; \
d[1] = 255 - _p.data8[1]; \
d[2] = 255 - _p.data8[2]; \
d[3] = 255; \
}
// blend_hline_invert_subpix
void
blend_hline_invert_subpix(int x, int y, unsigned len, const color_type& c,
uint8 cover, agg_buffer* buffer, const PatternHandler* pattern)
{
uint8* p = buffer->row_ptr(y) + (x << 2);
if(cover == 255) {
do {
if (pattern->IsHighColor(x, y)) {
ASSIGN_INVERT(p);
}
x++;
p += 4;
len -= 3;
} while (len);
} else {
do {
if (pattern->IsHighColor(x, y)) {
BLEND_INVERT(p, cover);
}
x++;
p += 4;
len -= 3;
} while (len);
}
}
// blend_solid_hspan_invert_subpix
void
blend_solid_hspan_invert_subpix(int x, int y, unsigned len, const color_type& c,
const uint8* covers, agg_buffer* buffer, const PatternHandler* pattern)
{
uint8* p = buffer->row_ptr(y) + (x << 2);
const int subpixelL = gSubpixelOrderingRGB ? 2 : 0;
const int subpixelM = 1;
const int subpixelR = gSubpixelOrderingRGB ? 0 : 2;
do {
if (pattern->IsHighColor(x, y))
BLEND_INVERT_SUBPIX(p, covers[2], covers[1], covers[0]);
if (pattern->IsHighColor(x, y)) {
BLEND_INVERT_SUBPIX(p, covers[subpixelL], covers[subpixelM],
covers[subpixelR]);
}
covers += 3;
p += 4;
x++;

View File

@ -11,6 +11,7 @@
#define DRAWING_MODE_MAX_SUBPIX_H
#include "DrawingMode.h"
#include "GlobalSubpixelSettings.h"
// BLEND_MAX_SUBPIX
#define BLEND_MAX_SUBPIX(d, r, g, b, a1, a2, a3) \
@ -24,73 +25,19 @@
}
// BLEND_MAX
#define BLEND_MAX(d, r, g, b, a) \
{ \
pixel32 _p; \
_p.data32 = *(uint32*)d; \
if (brightness_for((r), (g), (b)) \
> brightness_for(_p.data8[2], _p.data8[1], _p.data8[0])) { \
BLEND(d, (r), (g), (b), a); \
} \
}
// ASSIGN_MAX
#define ASSIGN_MAX(d, r, g, b) \
{ \
pixel32 _p; \
_p.data32 = *(uint32*)d; \
if (brightness_for((r), (g), (b)) \
> brightness_for(_p.data8[2], _p.data8[1], _p.data8[0])) { \
d[0] = (b); \
d[1] = (g); \
d[2] = (r); \
d[3] = 255; \
} \
}
// blend_hline_max_subpix
void
blend_hline_max_subpix(int x, int y, unsigned len, const color_type& c,
uint8 cover, agg_buffer* buffer, const PatternHandler* pattern)
{
uint8* p = buffer->row_ptr(y) + (x << 2);
if (cover == 255) {
do {
rgb_color color = pattern->ColorAt(x, y);
ASSIGN_MAX(p, color.red, color.green, color.blue);
p += 4;
x++;
len -= 3;
} while (len);
} else {
do {
rgb_color color = pattern->ColorAt(x, y);
BLEND_MAX(p, color.red, color.green, color.blue, cover);
x++;
p += 4;
len -= 3;
} while (len);
}
}
// blend_solid_hspan_max_subpix
void
blend_solid_hspan_max_subpix(int x, int y, unsigned len, const color_type& c,
const uint8* covers, agg_buffer* buffer, const PatternHandler* pattern)
{
uint8* p = buffer->row_ptr(y) + (x << 2);
const int subpixelL = gSubpixelOrderingRGB ? 2 : 0;
const int subpixelM = 1;
const int subpixelR = gSubpixelOrderingRGB ? 0 : 2;
do {
rgb_color color = pattern->ColorAt(x, y);
BLEND_MAX_SUBPIX(p, color.red, color.green, color.blue,
covers[2], covers[1], covers[0]);
covers[subpixelL], covers[subpixelM], covers[subpixelR]);
covers += 3;
p += 4;
x++;

View File

@ -11,6 +11,7 @@
#define DRAWING_MODE_MIN_SUBPIX_H
#include "DrawingMode.h"
#include "GlobalSubpixelSettings.h"
// BLEND_MIN_SUBPIX
#define BLEND_MIN_SUBPIX(d, r, g, b, a1, a2, a3) \
@ -24,73 +25,19 @@
}
// BLEND_MIN
#define BLEND_MIN(d, r, g, b, a) \
{ \
pixel32 _p; \
_p.data32 = *(uint32*)d; \
if (brightness_for((r), (g), (b)) \
< brightness_for(_p.data8[2], _p.data8[1], _p.data8[0])) { \
BLEND(d, (r), (g), (b), a); \
} \
}
// ASSIGN_MIN
#define ASSIGN_MIN(d, r, g, b) \
{ \
pixel32 _p; \
_p.data32 = *(uint32*)d; \
if (brightness_for((r), (g), (b)) \
< brightness_for(_p.data8[2], _p.data8[1], _p.data8[0])) { \
d[0] = (b); \
d[1] = (g); \
d[2] = (r); \
d[3] = 255; \
} \
}
// blend_hline_min_subpix
void
blend_hline_min_subpix(int x, int y, unsigned len, const color_type& c,
uint8 cover, agg_buffer* buffer, const PatternHandler* pattern)
{
uint8* p = buffer->row_ptr(y) + (x << 2);
if (cover == 255) {
do {
rgb_color color = pattern->ColorAt(x, y);
ASSIGN_MIN(p, color.red, color.green, color.blue);
p += 4;
x++;
len -= 3;
} while (len);
} else {
do {
rgb_color color = pattern->ColorAt(x, y);
BLEND_MIN(p, color.red, color.green, color.blue, cover);
x++;
p += 4;
len -= 3;
} while (len);
}
}
// blend_solid_hspan_min_subpix
void
blend_solid_hspan_min_subpix(int x, int y, unsigned len, const color_type& c,
const uint8* covers, agg_buffer* buffer, const PatternHandler* pattern)
{
uint8* p = buffer->row_ptr(y) + (x << 2);
const int subpixelL = gSubpixelOrderingRGB ? 2 : 0;
const int subpixelM = 1;
const int subpixelR = gSubpixelOrderingRGB ? 0 : 2;
do {
rgb_color color = pattern->ColorAt(x, y);
BLEND_MIN_SUBPIX(p, color.red, color.green, color.blue,
covers[2], covers[1], covers[0]);
covers[subpixelL], covers[subpixelM], covers[subpixelR]);
covers += 3;
p += 4;
x++;

View File

@ -11,6 +11,7 @@
#define DRAWING_MODE_OVER_SUBPIX_H
#include "DrawingMode.h"
#include "GlobalSubpixelSettings.h"
// BLEND_OVER_SUBPIX
#define BLEND_OVER_SUBPIX(d, r, g, b, a1, a2, a3) \
@ -19,58 +20,6 @@
}
// BLEND_OVER
#define BLEND_OVER(d, r, g, b, a) \
{ \
BLEND(d, r, g, b, a) \
}
// ASSIGN_OVER
#define ASSIGN_OVER(d, r, g, b) \
{ \
d[0] = (b); \
d[1] = (g); \
d[2] = (r); \
d[3] = 255; \
}
// blend_hline_over_subpix
void
blend_hline_over_subpix(int x, int y, unsigned len, const color_type& c,
uint8 cover, agg_buffer* buffer, const PatternHandler* pattern)
{
if (cover == 255) {
rgb_color color = pattern->HighColor();
uint32 v;
uint8* p8 = (uint8*)&v;
p8[0] = (uint8)color.blue;
p8[1] = (uint8)color.green;
p8[2] = (uint8)color.red;
p8[3] = 255;
uint32* p32 = (uint32*)(buffer->row_ptr(y)) + x;
do {
if (pattern->IsHighColor(x, y))
*p32 = v;
p32++;
x++;
len -= 3;
} while (len);
} else {
uint8* p = buffer->row_ptr(y) + (x << 2);
rgb_color color = pattern->HighColor();
do {
if (pattern->IsHighColor(x, y))
BLEND_OVER(p, color.red, color.green, color.blue, cover);
x++;
p += 4;
len -= 3;
} while (len);
}
}
// blend_solid_hspan_over_subpix
void
blend_solid_hspan_over_subpix(int x, int y, unsigned len, const color_type& c,
@ -78,10 +27,13 @@ blend_solid_hspan_over_subpix(int x, int y, unsigned len, const color_type& c,
{
uint8* p = buffer->row_ptr(y) + (x << 2);
rgb_color color = pattern->HighColor();
const int subpixelL = gSubpixelOrderingRGB ? 2 : 0;
const int subpixelM = 1;
const int subpixelR = gSubpixelOrderingRGB ? 0 : 2;
do {
if (pattern->IsHighColor(x, y)) {
BLEND_OVER_SUBPIX(p, color.red, color.green, color.blue,
covers[2], covers[1], covers[0]);
covers[subpixelL], covers[subpixelM], covers[subpixelR]);
}
covers += 3;
p += 4;

View File

@ -11,40 +11,7 @@
#define DRAWING_MODE_OVER_SOLID_SUBPIX_H
#include "DrawingModeOverSUBPIX.h"
// blend_hline_over_solid_subpix
void
blend_hline_over_solid_subpix(int x, int y, unsigned len, const color_type& c,
uint8 cover, agg_buffer* buffer, const PatternHandler* pattern)
{
if (pattern->IsSolidLow())
return;
if (cover == 255) {
uint32 v;
uint8* p8 = (uint8*)&v;
p8[0] = (uint8)c.b;
p8[1] = (uint8)c.g;
p8[2] = (uint8)c.r;
p8[3] = 255;
uint32* p32 = (uint32*)(buffer->row_ptr(y)) + x;
do {
*p32 = v;
p32++;
x++;
len -= 3;
} while (len);
} else {
uint8* p = buffer->row_ptr(y) + (x << 2);
do {
BLEND_OVER(p, c.r, c.g, c.b, cover);
x++;
p += 4;
len -= 3;
} while (len);
}
}
#include "GlobalSubpixelSettings.h"
// blend_solid_hspan_over_solid_subpix
void
@ -56,8 +23,12 @@ blend_solid_hspan_over_solid_subpix(int x, int y, unsigned len,
return;
uint8* p = buffer->row_ptr(y) + (x << 2);
const int subpixelL = gSubpixelOrderingRGB ? 2 : 0;
const int subpixelM = 1;
const int subpixelR = gSubpixelOrderingRGB ? 0 : 2;
do {
BLEND_OVER_SUBPIX(p, c.r, c.g, c.b, covers[2], covers[1], covers[0]);
BLEND_OVER_SUBPIX(p, c.r, c.g, c.b,
covers[subpixelL], covers[subpixelM], covers[subpixelR]);
covers += 3;
p += 4;
x++;

View File

@ -11,6 +11,7 @@
#define DRAWING_MODE_SELECT_SUBPIX_H
#include "DrawingMode.h"
#include "GlobalSubpixelSettings.h"
// BLEND_SELECT_SUBPIX
#define BLEND_SELECT_SUBPIX(d, r, g, b, a1, a2, a3) \
@ -19,55 +20,6 @@
}
// BLEND_SELECT
#define BLEND_SELECT(d, r, g, b, a) \
{ \
BLEND(d, r, g, b, a); \
}
// ASSIGN_SELECT
#define ASSIGN_SELECT(d, r, g, b) \
{ \
d[0] = (b); \
d[1] = (g); \
d[2] = (r); \
d[3] = 255; \
}
// blend_hline_select_subpix
void
blend_hline_select_subpix(int x, int y, unsigned len, const color_type& c,
uint8 cover, agg_buffer* buffer, const PatternHandler* pattern)
{
uint8* p = buffer->row_ptr(y) + (x << 2);
rgb_color high = pattern->HighColor();
rgb_color low = pattern->LowColor();
rgb_color color;
if (cover == 255) {
do {
if (pattern->IsHighColor(x, y)
&& compare(p, high, low, &color))
ASSIGN_SELECT(p, color.red, color.green, color.blue);
x++;
p += 4;
len -= 3;
} while (len);
} else {
do {
if (pattern->IsHighColor(x, y)
&& compare(p, high, low, &color)) {
BLEND_SELECT(p, color.red, color.green, color.blue, cover);
}
x++;
p += 4;
len -= 3;
} while (len);
}
}
// blend_solid_hspan_select_subpix
void
blend_solid_hspan_select_subpix(int x, int y, unsigned len, const color_type& c,
@ -77,11 +29,14 @@ blend_solid_hspan_select_subpix(int x, int y, unsigned len, const color_type& c,
rgb_color high = pattern->HighColor();
rgb_color low = pattern->LowColor();
rgb_color color;
const int subpixelL = gSubpixelOrderingRGB ? 2 : 0;
const int subpixelM = 1;
const int subpixelR = gSubpixelOrderingRGB ? 0 : 2;
do {
if (pattern->IsHighColor(x, y)) {
if (compare(p, high, low, &color)){
BLEND_SELECT_SUBPIX(p, color.red, color.green, color.blue,
covers[2], covers[1], covers[0]);
covers[subpixelL], covers[subpixelM], covers[subpixelR]);
}
}
covers += 3;

View File

@ -10,10 +10,8 @@
#ifndef DRAWING_MODE_SUBTRACT_SUBPIX_H
#define DRAWING_MODE_SUBTRACT_SUBPIX_H
#include <SupportDefs.h>
#include "DrawingMode.h"
#include "PatternHandler.h"
#include "GlobalSubpixelSettings.h"
// BLEND_SUBTRACT_SUBPIX
#define BLEND_SUBTRACT_SUBPIX(d, r, g, b, a1, a2, a3) \
@ -27,60 +25,6 @@
}
// BLEND_SUBTRACT
#define BLEND_SUBTRACT(d, r, g, b, a) \
{ \
pixel32 _p; \
_p.data32 = *(uint32*)d; \
uint8 rt = max_c(0, _p.data8[2] - (r)); \
uint8 gt = max_c(0, _p.data8[1] - (g)); \
uint8 bt = max_c(0, _p.data8[0] - (b)); \
BLEND(d, rt, gt, bt, a); \
}
// ASSIGN_SUBTRACT
#define ASSIGN_SUBTRACT(d, r, g, b) \
{ \
pixel32 _p; \
_p.data32 = *(uint32*)d; \
d[0] = max_c(0, _p.data8[0] - (b)); \
d[1] = max_c(0, _p.data8[1] - (g)); \
d[2] = max_c(0, _p.data8[2] - (r)); \
d[3] = 255; \
}
// blend_hline_subtract_subpix
void
blend_hline_subtract_subpix(int x, int y, unsigned len, const color_type& c,
uint8 cover, agg_buffer* buffer, const PatternHandler* pattern)
{
uint8* p = buffer->row_ptr(y) + (x << 2);
if (cover == 255) {
do {
rgb_color color = pattern->ColorAt(x, y);
ASSIGN_SUBTRACT(p, color.red, color.green, color.blue);
p += 4;
x++;
len -= 3;
} while (len);
} else {
do {
rgb_color color = pattern->ColorAt(x, y);
BLEND_SUBTRACT(p, color.red, color.green, color.blue, cover);
x++;
p += 4;
len -= 3;
} while (len);
}
}
// blend_solid_hspan_subtract_subpix
void
blend_solid_hspan_subtract_subpix(int x, int y, unsigned len,
@ -88,10 +32,13 @@ blend_solid_hspan_subtract_subpix(int x, int y, unsigned len,
const PatternHandler* pattern)
{
uint8* p = buffer->row_ptr(y) + (x << 2);
const int subpixelL = gSubpixelOrderingRGB ? 2 : 0;
const int subpixelM = 1;
const int subpixelR = gSubpixelOrderingRGB ? 0 : 2;
do {
rgb_color color = pattern->ColorAt(x, y);
BLEND_SUBTRACT_SUBPIX(p, color.red, color.green, color.blue,
covers[2], covers[1], covers[0]);
covers[subpixelL], covers[subpixelM], covers[subpixelR]);
covers += 3;
p += 4;
x++;

View File

@ -74,15 +74,6 @@ blend_hline_empty(int x, int y, unsigned len,
printf("blend_hline_empty()\n");
}
// blend_hline_subpix_empty
void
blend_hline_empty_subpix(int x, int y, unsigned len,
const color_type& c, uint8 cover,
agg_buffer* buffer, const PatternHandler* pattern)
{
printf("blend_hline_empty_subpix()\n");
}
// blend_vline_empty
void
blend_vline_empty(int x, int y, unsigned len,
@ -151,7 +142,6 @@ PixelFormat::PixelFormat(agg::rendering_buffer& rb,
fBlendPixel(blend_pixel_empty),
fBlendHLine(blend_hline_empty),
fBlendHLineSubpix(blend_hline_empty_subpix),
fBlendVLine(blend_vline_empty),
fBlendSolidHSpan(blend_solid_hspan_empty),
fBlendSolidHSpanSubpix(blend_solid_hspan_empty_subpix),
@ -181,12 +171,10 @@ PixelFormat::SetDrawingMode(drawing_mode mode, source_alpha alphaSrcMode,
fBlendHLine = blend_hline_over_solid;
fBlendSolidHSpan = blend_solid_hspan_over_solid;
fBlendSolidVSpan = blend_solid_vspan_over_solid;
fBlendHLineSubpix = blend_hline_over_solid_subpix;
fBlendSolidHSpanSubpix = blend_solid_hspan_over_solid_subpix;
} else {
fBlendPixel = blend_pixel_over;
fBlendHLine = blend_hline_over;
fBlendHLineSubpix = blend_hline_over_subpix;
fBlendSolidHSpanSubpix = blend_solid_hspan_over_subpix;
fBlendSolidHSpan = blend_solid_hspan_over;
fBlendSolidVSpan = blend_solid_vspan_over;
@ -196,7 +184,6 @@ PixelFormat::SetDrawingMode(drawing_mode mode, source_alpha alphaSrcMode,
case B_OP_ERASE:
fBlendPixel = blend_pixel_erase;
fBlendHLine = blend_hline_erase;
fBlendHLineSubpix = blend_hline_erase_subpix;
fBlendSolidHSpanSubpix = blend_solid_hspan_erase_subpix;
fBlendSolidHSpan = blend_solid_hspan_erase;
fBlendSolidVSpan = blend_solid_vspan_erase;
@ -205,7 +192,6 @@ PixelFormat::SetDrawingMode(drawing_mode mode, source_alpha alphaSrcMode,
case B_OP_INVERT:
fBlendPixel = blend_pixel_invert;
fBlendHLine = blend_hline_invert;
fBlendHLineSubpix = blend_hline_invert_subpix;
fBlendSolidHSpanSubpix = blend_solid_hspan_invert_subpix;
fBlendSolidHSpan = blend_solid_hspan_invert;
fBlendSolidVSpan = blend_solid_vspan_invert;
@ -214,7 +200,6 @@ PixelFormat::SetDrawingMode(drawing_mode mode, source_alpha alphaSrcMode,
case B_OP_SELECT:
fBlendPixel = blend_pixel_select;
fBlendHLine = blend_hline_select;
fBlendHLineSubpix = blend_hline_select_subpix;
fBlendSolidHSpanSubpix = blend_solid_hspan_select_subpix;
fBlendSolidHSpan = blend_solid_hspan_select;
fBlendSolidVSpan = blend_solid_vspan_select;
@ -227,7 +212,6 @@ PixelFormat::SetDrawingMode(drawing_mode mode, source_alpha alphaSrcMode,
if (text) {
fBlendPixel = blend_pixel_copy_text;
fBlendHLine = blend_hline_copy_text;
fBlendHLineSubpix = blend_hline_copy_text_subpix;
fBlendSolidHSpanSubpix = blend_solid_hspan_copy_text_subpix;
fBlendSolidHSpan = blend_solid_hspan_copy_text;
fBlendSolidVSpan = blend_solid_vspan_copy_text;
@ -239,7 +223,6 @@ PixelFormat::SetDrawingMode(drawing_mode mode, source_alpha alphaSrcMode,
} else if (fPatternHandler->IsSolid()) {
fBlendPixel = blend_pixel_copy_solid;
fBlendHLine = blend_hline_copy_solid;
fBlendHLineSubpix = blend_hline_copy_solid_subpix;
fBlendSolidHSpanSubpix = blend_solid_hspan_copy_solid_subpix;
fBlendSolidHSpan = blend_solid_hspan_copy_solid;
fBlendSolidVSpan = blend_solid_vspan_copy_solid;
@ -247,7 +230,6 @@ PixelFormat::SetDrawingMode(drawing_mode mode, source_alpha alphaSrcMode,
} else {
fBlendPixel = blend_pixel_copy;
fBlendHLine = blend_hline_copy;
fBlendHLineSubpix = blend_hline_copy_subpix;
fBlendSolidHSpanSubpix = blend_solid_hspan_copy_subpix;
fBlendSolidHSpan = blend_solid_hspan_copy;
fBlendSolidVSpan = blend_solid_vspan_copy;
@ -256,8 +238,7 @@ PixelFormat::SetDrawingMode(drawing_mode mode, source_alpha alphaSrcMode,
break;
case B_OP_ADD:
fBlendPixel = blend_pixel_add;
fBlendHLine = blend_hline_add;
fBlendHLineSubpix = blend_hline_add_subpix;
fBlendHLine = blend_hline_add;
fBlendSolidHSpanSubpix = blend_solid_hspan_add_subpix;
fBlendSolidHSpan = blend_solid_hspan_add;
fBlendSolidVSpan = blend_solid_vspan_add;
@ -266,7 +247,6 @@ PixelFormat::SetDrawingMode(drawing_mode mode, source_alpha alphaSrcMode,
case B_OP_SUBTRACT:
fBlendPixel = blend_pixel_subtract;
fBlendHLine = blend_hline_subtract;
fBlendHLineSubpix = blend_hline_subtract_subpix;
fBlendSolidHSpanSubpix = blend_solid_hspan_subtract_subpix;
fBlendSolidHSpan = blend_solid_hspan_subtract;
fBlendSolidVSpan = blend_solid_vspan_subtract;
@ -275,7 +255,6 @@ PixelFormat::SetDrawingMode(drawing_mode mode, source_alpha alphaSrcMode,
case B_OP_BLEND:
fBlendPixel = blend_pixel_blend;
fBlendHLine = blend_hline_blend;
fBlendHLineSubpix = blend_hline_blend_subpix;
fBlendSolidHSpanSubpix = blend_solid_hspan_blend_subpix;
fBlendSolidHSpan = blend_solid_hspan_blend;
fBlendSolidVSpan = blend_solid_vspan_blend;
@ -284,7 +263,6 @@ PixelFormat::SetDrawingMode(drawing_mode mode, source_alpha alphaSrcMode,
case B_OP_MIN:
fBlendPixel = blend_pixel_min;
fBlendHLine = blend_hline_min;
fBlendHLineSubpix = blend_hline_min_subpix;
fBlendSolidHSpanSubpix = blend_solid_hspan_min_subpix;
fBlendSolidHSpan = blend_solid_hspan_min;
fBlendSolidVSpan = blend_solid_vspan_min;
@ -293,7 +271,6 @@ PixelFormat::SetDrawingMode(drawing_mode mode, source_alpha alphaSrcMode,
case B_OP_MAX:
fBlendPixel = blend_pixel_max;
fBlendHLine = blend_hline_max;
fBlendHLineSubpix = blend_hline_max_subpix;
fBlendSolidHSpanSubpix = blend_solid_hspan_max_subpix;
fBlendSolidHSpan = blend_solid_hspan_max;
fBlendSolidVSpan = blend_solid_vspan_max;
@ -314,14 +291,12 @@ PixelFormat::SetDrawingMode(drawing_mode mode, source_alpha alphaSrcMode,
if (fPatternHandler->IsSolid()) {
fBlendPixel = blend_pixel_alpha_co_solid;
fBlendHLine = blend_hline_alpha_co_solid;
fBlendHLineSubpix = blend_hline_alpha_co_solid_subpix;
fBlendSolidHSpanSubpix = blend_solid_hspan_alpha_co_solid_subpix;
fBlendSolidHSpan = blend_solid_hspan_alpha_co_solid;
fBlendSolidVSpan = blend_solid_vspan_alpha_co_solid;
} else {
fBlendPixel = blend_pixel_alpha_co;
fBlendHLine = blend_hline_alpha_co;
fBlendHLineSubpix = blend_hline_alpha_co_subpix;
fBlendSolidHSpanSubpix = blend_solid_hspan_alpha_co_subpix;
fBlendSolidHSpan = blend_solid_hspan_alpha_co;
fBlendSolidVSpan = blend_solid_vspan_alpha_co;
@ -330,7 +305,6 @@ PixelFormat::SetDrawingMode(drawing_mode mode, source_alpha alphaSrcMode,
} else if (alphaFncMode == B_ALPHA_COMPOSITE) {
fBlendPixel = blend_pixel_alpha_cc;
fBlendHLine = blend_hline_alpha_cc;
fBlendHLineSubpix = blend_hline_alpha_cc_subpix;
fBlendSolidHSpanSubpix = blend_solid_hspan_alpha_cc_subpix;
fBlendSolidHSpan = blend_solid_hspan_alpha_cc;
fBlendSolidVSpan = blend_solid_vspan_alpha_cc;
@ -341,14 +315,12 @@ PixelFormat::SetDrawingMode(drawing_mode mode, source_alpha alphaSrcMode,
if (fPatternHandler->IsSolid()) {
fBlendPixel = blend_pixel_alpha_po_solid;
fBlendHLine = blend_hline_alpha_po_solid;
fBlendHLineSubpix = blend_hline_alpha_po_solid_subpix;
fBlendSolidHSpanSubpix = blend_solid_hspan_alpha_po_solid_subpix;
fBlendSolidHSpan = blend_solid_hspan_alpha_po_solid;
fBlendSolidVSpan = blend_solid_vspan_alpha_po_solid;
} else {
fBlendPixel = blend_pixel_alpha_po;
fBlendHLine = blend_hline_alpha_po;
fBlendHLineSubpix = blend_hline_alpha_po_subpix;
fBlendSolidHSpanSubpix = blend_solid_hspan_alpha_po_subpix;
fBlendSolidHSpan = blend_solid_hspan_alpha_po;
fBlendSolidVSpan = blend_solid_vspan_alpha_po;
@ -357,7 +329,6 @@ PixelFormat::SetDrawingMode(drawing_mode mode, source_alpha alphaSrcMode,
} else if (alphaFncMode == B_ALPHA_COMPOSITE) {
fBlendPixel = blend_pixel_alpha_pc;
fBlendHLine = blend_hline_alpha_pc;
fBlendHLineSubpix = blend_hline_alpha_pc_subpix;
fBlendSolidHSpanSubpix = blend_solid_hspan_alpha_pc_subpix;
fBlendSolidHSpan = blend_solid_hspan_alpha_pc;
fBlendSolidVSpan = blend_solid_vspan_alpha_pc;

View File

@ -105,11 +105,6 @@ class PixelFormat {
const color_type& c,
uint8 cover);
inline void blend_hline_subpix(int x, int y,
unsigned len,
const color_type& c,
uint8 cover);
inline void blend_vline(int x, int y,
unsigned len,
const color_type& c,
@ -149,7 +144,6 @@ class PixelFormat {
blend_pixel_f fBlendPixel;
blend_line fBlendHLine;
blend_line fBlendHLineSubpix;
blend_line fBlendVLine;
blend_solid_span fBlendSolidHSpan;
blend_solid_span fBlendSolidHSpanSubpix;
@ -211,14 +205,6 @@ PixelFormat::blend_hline(int x, int y, unsigned len,
fBlendHLine(x, y, len, c, cover, fBuffer, fPatternHandler);
}
// blend_hline_subpix
inline void
PixelFormat::blend_hline_subpix(int x, int y, unsigned len,
const color_type& c, uint8 cover)
{
fBlendHLineSubpix(x, y, len, c, cover, fBuffer, fPatternHandler);
}
// blend_vline
inline void
PixelFormat::blend_vline(int x, int y, unsigned len,

View File

@ -70,6 +70,7 @@ SharedLibrary libhaikuappserver.so :
FontFamily.cpp
FontManager.cpp
FontStyle.cpp
GlobalSubpixelSettings.cpp
HashTable.cpp
IntPoint.cpp
IntRect.cpp