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:
parent
826df7bec8
commit
59e13a3f06
@ -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())
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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++)
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
59
src/preferences/appearance/AntialiasingSettingsView.h
Normal file
59
src/preferences/appearance/AntialiasingSettingsView.h
Normal 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
|
@ -5,6 +5,7 @@ UsePrivateHeaders app [ FDirName servers app ] ;
|
||||
|
||||
Preference Appearance :
|
||||
APRMain.cpp
|
||||
AntialiasingSettingsView.cpp
|
||||
APRView.cpp
|
||||
APRWindow.cpp
|
||||
ColorSet.cpp
|
||||
|
@ -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 */
|
@ -12,7 +12,6 @@
|
||||
|
||||
|
||||
#include "FontSelectionView.h"
|
||||
#include "AdvancedSettingsView.h"
|
||||
|
||||
|
||||
class FontView : public BView {
|
||||
|
@ -5,7 +5,6 @@ AddSubDirSupportedPlatforms libbe_test ;
|
||||
|
||||
Preference Fonts :
|
||||
FontSelectionView.cpp
|
||||
AdvancedSettingsView.cpp
|
||||
FontsSettings.cpp
|
||||
FontView.cpp
|
||||
main.cpp
|
||||
|
@ -63,8 +63,6 @@ MainWindow::MainWindow()
|
||||
rect = tabView->ContainerView()->Bounds().InsetByCopy(5, 8);
|
||||
fFontsView = new FontView(rect);
|
||||
|
||||
fAdvancedSettings = new AdvancedSettingsView(rect, "Advanced");
|
||||
|
||||
tabView->AddTab(fFontsView);
|
||||
|
||||
fFontsView->UpdateFonts();
|
||||
@ -104,23 +102,6 @@ MainWindow::MainWindow()
|
||||
_Center();
|
||||
}
|
||||
|
||||
tabView->AddTab(fAdvancedSettings);
|
||||
|
||||
fAdvancedSettings->RelayoutIfNeeded();
|
||||
fAdvancedSettings->GetPreferredSize(&width, &height);
|
||||
|
||||
widthDiff = width + 10 - tabView->ContainerView()->Bounds().Width();
|
||||
if (widthDiff > 0) {
|
||||
tabView->ResizeBy(widthDiff, 0);
|
||||
tabView->ContainerView()->ResizeBy(widthDiff, 0);
|
||||
}
|
||||
|
||||
heightDiff = height + 16 - tabView->ContainerView()->Bounds().Height();
|
||||
if (heightDiff > 0) {
|
||||
tabView->ResizeBy(0, heightDiff);
|
||||
tabView->ContainerView()->ResizeBy(0, heightDiff);
|
||||
}
|
||||
|
||||
fRunner = new BMessageRunner(this, new BMessage(kMsgCheckFonts), 3000000);
|
||||
// every 3 seconds
|
||||
|
||||
@ -149,25 +130,19 @@ MainWindow::MessageReceived(BMessage *message)
|
||||
{
|
||||
switch (message->what) {
|
||||
case kMsgUpdate:
|
||||
fDefaultsButton->SetEnabled(fFontsView->IsDefaultable()
|
||||
|| fAdvancedSettings->IsDefaultable());
|
||||
fRevertButton->SetEnabled(fFontsView->IsRevertable()
|
||||
|| fAdvancedSettings->IsRevertable());
|
||||
fDefaultsButton->SetEnabled(fFontsView->IsDefaultable());
|
||||
fRevertButton->SetEnabled(fFontsView->IsRevertable());
|
||||
break;
|
||||
|
||||
case kMsgSetDefaults:
|
||||
fFontsView->SetDefaults();
|
||||
fAdvancedSettings->SetDefaults();
|
||||
fDefaultsButton->SetEnabled(false);
|
||||
fRevertButton->SetEnabled(fFontsView->IsRevertable()
|
||||
|| fAdvancedSettings->IsRevertable());
|
||||
fRevertButton->SetEnabled(fFontsView->IsRevertable());
|
||||
break;
|
||||
|
||||
case kMsgRevert:
|
||||
fFontsView->Revert();
|
||||
fAdvancedSettings->Revert();
|
||||
fDefaultsButton->SetEnabled(fFontsView->IsDefaultable()
|
||||
|| fAdvancedSettings->IsDefaultable());
|
||||
fDefaultsButton->SetEnabled(fFontsView->IsDefaultable());
|
||||
fRevertButton->SetEnabled(false);
|
||||
break;
|
||||
|
||||
|
@ -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';
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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 };
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
14
src/servers/app/drawing/Painter/GlobalSubpixelSettings.cpp
Normal file
14
src/servers/app/drawing/Painter/GlobalSubpixelSettings.cpp
Normal 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;
|
29
src/servers/app/drawing/Painter/GlobalSubpixelSettings.h
Normal file
29
src/servers/app/drawing/Painter/GlobalSubpixelSettings.h
Normal 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
|
||||
|
||||
|
@ -13,6 +13,7 @@ UseFreeTypeHeaders ;
|
||||
SEARCH_SOURCE += [ FDirName $(SUBDIR) drawing_modes ] ;
|
||||
|
||||
StaticLibrary libpainter.a :
|
||||
GlobalSubpixelSettings.cpp
|
||||
Painter.cpp
|
||||
Transformable.cpp
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
167
src/servers/app/drawing/Painter/agg_scanline_p_subpix.h
Normal file
167
src/servers/app/drawing/Painter/agg_scanline_p_subpix.h
Normal 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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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++;
|
||||
|
@ -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++;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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++;
|
||||
|
@ -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++;
|
||||
|
@ -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++;
|
||||
|
@ -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++;
|
||||
|
@ -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;
|
||||
|
@ -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++;
|
||||
|
@ -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++;
|
||||
|
@ -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++;
|
||||
|
@ -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;
|
||||
|
@ -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++;
|
||||
|
@ -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;
|
||||
|
@ -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++;
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -70,6 +70,7 @@ SharedLibrary libhaikuappserver.so :
|
||||
FontFamily.cpp
|
||||
FontManager.cpp
|
||||
FontStyle.cpp
|
||||
GlobalSubpixelSettings.cpp
|
||||
HashTable.cpp
|
||||
IntPoint.cpp
|
||||
IntRect.cpp
|
||||
|
Loading…
Reference in New Issue
Block a user