Created
May 18, 2025 23:55
-
-
Save X547/1ce273adfee14ba6f4a67406b9906720 to your computer and use it in GitHub Desktop.
app_server_neo Canvas interface
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <string_view> | |
#include <optional> | |
#include <Point.h> | |
#include <Rect.h> | |
#include <Region.h> | |
#include <Shape.h> | |
#include <Font.h> | |
#include <View.h> | |
#include <AffineTransform.h> | |
#include <Gradient.h> | |
#include <InterfaceDefs.h> | |
#include <app_server/generated/ProtocolTypes.h> | |
#include <app_server/Typeface.h> | |
namespace AppServer { | |
class Picture; | |
class Bitmap; | |
class Window; | |
struct CanvasFontState { | |
set_font_mask dirty = (set_font_mask)0; | |
BReference<Typeface> typeface; | |
float size = 12.0f; | |
float shear = 90.0f; | |
float rotation = 0.0f; | |
float falseBoldWidth = 0.0f; | |
int8 spacing = B_BITMAP_SPACING; // B_*_SPACING | |
int8 encoding = B_UNICODE_UTF8; // B_UNICODE_UTF8, ... | |
int16 face = B_REGULAR_FACE; // B_*_FACE | |
int32 flags = 0; // B_DISABLE_ANTIALIASING, B_FORCE_ANTIALIASING | |
}; | |
enum CanvasStateField { | |
CanvasState_penLocation, | |
CanvasState_penSize, | |
CanvasState_highColor, | |
CanvasState_lowColor, | |
CanvasState_whichHighColor, | |
CanvasState_whichLowColor, | |
CanvasState_pattern, | |
CanvasState_drawingMode, | |
CanvasState_origin, | |
CanvasState_scale, | |
CanvasState_lineMode, | |
CanvasState_fillRule, | |
CanvasState_blendingMode, | |
CanvasState_fontAntialiasing, | |
CanvasState_transform, | |
CanvasState_clipRegion, | |
CanvasState_font, | |
CanvasGlobalState_origin, | |
CanvasGlobalState_clipRegion, | |
CanvasGlobalState_subpixelPrecise, | |
}; | |
struct CanvasGlobalState { | |
uint32 dirty = 0; | |
BPoint origin; | |
BRegion* clipRegion {}; | |
bool subpixelPrecise: 1 = false; | |
}; | |
struct CanvasState { | |
uint32 dirty = 0; | |
BPoint penLocation; | |
float penSize = 1.0f; | |
rgb_color highColor = {0, 0, 0, 255}; | |
rgb_color lowColor = {255, 255, 255, 255}; | |
color_which whichHighColor = B_NO_COLOR; | |
color_which whichLowColor = B_NO_COLOR; | |
float whichHighColorTint = B_NO_TINT; | |
float whichLowColorTint = B_NO_TINT; | |
::pattern pattern = B_SOLID_HIGH; | |
drawing_mode drawingMode = B_OP_COPY; | |
BPoint origin; | |
float scale = 1.0f; | |
join_mode lineJoin = B_MITER_JOIN; | |
cap_mode lineCap = B_BUTT_CAP; | |
float miterLimit = B_DEFAULT_MITER_LIMIT; | |
int32 fillRule = B_NONZERO; | |
source_alpha alphaSourceMode = B_PIXEL_ALPHA; | |
alpha_function alphaFunctionMode = B_ALPHA_OVERLAY; | |
bool subpixelPrecise: 1 = false; | |
bool fontAntialiasing: 1 = false; | |
BAffineTransform baseTransform; | |
BAffineTransform transform; | |
std::optional<BRegion> clipRegion; | |
CanvasFontState font; | |
inline void MovePenTo(BPoint val); | |
inline void SetPenSize(float val); | |
inline void SetHighColor(rgb_color val); | |
inline void SetHighUIColor(color_which which, float tint = B_NO_TINT); | |
inline void SetLowColor(rgb_color val); | |
inline void SetLowUIColor(color_which which, float tint = B_NO_TINT); | |
inline void SetPattern(::pattern val); | |
inline void SetDrawingMode(drawing_mode val); | |
inline void SetOrigin(BPoint val); | |
inline void SetScale(float val); | |
inline void SetLineMode(cap_mode lineCap, join_mode lineJoin, float miterLimit); | |
inline void SetFillRule(int32 val); | |
inline void SetBlendingMode(source_alpha srcAlpha, alpha_function alphaFunc); | |
inline void ForceFontAliasing(bool enable); | |
inline void SetTransform(const BAffineTransform& val); | |
inline BRegion& SetClipRegion(); | |
inline void ClearClipRegion(); | |
inline BAffineTransform CombinedTransform(); | |
}; | |
class Canvas { | |
public: | |
class GlobalStateHandler { | |
public: | |
virtual void Fetch() = 0; | |
}; | |
public: | |
virtual ~Canvas() = default; | |
virtual CanvasState& State() = 0; | |
virtual CanvasGlobalState& GlobalState() = 0; | |
virtual void SetGlobalStateHandler(GlobalStateHandler* handler) = 0; | |
virtual void Flush() = 0; | |
// state | |
virtual void PushState() = 0; | |
virtual void PopState() = 0; | |
virtual void BeginLayer(uint8 opacity) = 0; | |
virtual void EndLayer() = 0; | |
virtual void TranslateBy(double x, double y) = 0; | |
virtual void ScaleBy(double x, double y) = 0; | |
virtual void RotateBy(double angleRadians) = 0; | |
// clipping | |
virtual void ConstrainClippingRegion(const BRegion* region) = 0; | |
virtual void GetClippingRegion(BRegion* region) = 0; | |
virtual void ClipToPicture(Picture* picture, BPoint where, bool invert) = 0; | |
virtual void ClipToRect(bool inverse, BRect rect) = 0; | |
virtual void ClipToShape(bool inverse, const BShape& shape) = 0; | |
// drawing | |
virtual void CopyBits(BRect src, BRect dst) = 0; | |
virtual void StrokeLine(BPoint startPoint, BPoint endPoint) = 0; | |
virtual void InvertRect(BRect rect) = 0; | |
virtual void StrokeRect(BRect rect) = 0; | |
virtual void FillRect(BRect rect) = 0; | |
virtual void FillRect(BRect rect, const BGradient& gradient) = 0; | |
virtual void DrawBitmap(Bitmap* bitmap, bitmap_drawing_options options, BRect viewRect, BRect bitmapRect) = 0; | |
virtual void StrokeArc(BRect rect, float startAngle, float arcAngle) = 0; | |
virtual void FillArc(BRect rect, float startAngle, float arcAngle) = 0; | |
virtual void FillArc(BRect rect, float startAngle, float arcAngle, const BGradient& gradient) = 0; | |
virtual void StrokeBezier(const BPoint controlPoints[4]) = 0; | |
virtual void FillBezier(const BPoint controlPoints[4]) = 0; | |
virtual void FillBezier(const BPoint controlPoints[4], const BGradient& gradient) = 0; | |
virtual void StrokeEllipse(BRect rect) = 0; | |
virtual void FillEllipse(BRect rect) = 0; | |
virtual void FillEllipse(BRect rect, const BGradient& gradient) = 0; | |
virtual void StrokeRoundRect(BRect rect, float xRadius, float yRadius) = 0; | |
virtual void FillRoundRect(BRect rect, float xRadius, float yRadius) = 0; | |
virtual void FillRoundRect(BRect rect, float xRadius, float yRadius, const BGradient& gradient) = 0; | |
virtual void StrokeTriangle(const BPoint points[3], BRect bounds) = 0; | |
virtual void FillTriangle(const BPoint points[3], BRect bounds) = 0; | |
virtual void FillTriangle(const BPoint points[3], BRect bounds, const BGradient& gradient) = 0; | |
virtual void StrokePolygon(BRect bounds, bool closed, int32 count, const BPoint* points) = 0; | |
virtual void FillPolygon(BRect bounds, int32 count, const BPoint* points) = 0; | |
virtual void FillPolygon(BRect bounds, int32 count, const BPoint* points, const BGradient& gradient) = 0; | |
virtual void StrokeShape(const BShape& shape) = 0; | |
virtual void FillShape(const BShape& shape) = 0; | |
virtual void FillShape(const BShape& shape, const BGradient& gradient) = 0; | |
virtual void FillRegion(const BRegion& region) = 0; | |
virtual void FillRegion(const BRegion& region, const BGradient& gradient) = 0; | |
virtual void StrokeLineArray(int32 count, const ViewLineArrayInfo* array) = 0; | |
virtual void DrawString(std::string_view string, BPoint location, const escapement_delta* delta) = 0; | |
virtual void DrawStringWithOffsets(std::string_view string, int32 locationCount, const BPoint* locations) = 0; | |
virtual void DrawPicture(Picture* picture, BPoint where) = 0; | |
protected: | |
}; | |
class UpdateTrackingCanvas final: public Canvas { | |
public: | |
class Handler { | |
public: | |
virtual void Update() = 0; | |
virtual void Update(const BRect& dirty) = 0; | |
virtual void Update(const BRegion& dirty) = 0; | |
}; | |
virtual ~UpdateTrackingCanvas() = default; | |
UpdateTrackingCanvas(Canvas* base): fBase(base) {} | |
void SetHandler(Handler* handler) {fHandler = handler;} | |
CanvasState& State() final; | |
CanvasGlobalState& GlobalState() final; | |
void SetGlobalStateHandler(GlobalStateHandler* handler) final; | |
void Flush() final; | |
// state | |
void PushState() final; | |
void PopState() final; | |
void BeginLayer(uint8 opacity) final; | |
void EndLayer() final; | |
void TranslateBy(double x, double y) final; | |
void ScaleBy(double x, double y) final; | |
void RotateBy(double angleRadians) final; | |
// clipping | |
void ConstrainClippingRegion(const BRegion* region) final; | |
void GetClippingRegion(BRegion* region) final; | |
void ClipToPicture(Picture* picture, BPoint where, bool invert) final; | |
void ClipToRect(bool inverse, BRect rect) final; | |
void ClipToShape(bool inverse, const BShape& shape) final; | |
// drawing | |
void CopyBits(BRect src, BRect dst) final; | |
void StrokeLine(BPoint startPoint, BPoint endPoint) final; | |
void InvertRect(BRect rect) final; | |
void StrokeRect(BRect rect) final; | |
void FillRect(BRect rect) final; | |
void FillRect(BRect rect, const BGradient& gradient) final; | |
void DrawBitmap(Bitmap* bitmap, bitmap_drawing_options options, BRect viewRect, BRect bitmapRect) final; | |
void StrokeArc(BRect rect, float startAngle, float arcAngle) final; | |
void FillArc(BRect rect, float startAngle, float arcAngle) final; | |
void FillArc(BRect rect, float startAngle, float arcAngle, const BGradient& gradient) final; | |
void StrokeBezier(const BPoint controlPoints[4]) final; | |
void FillBezier(const BPoint controlPoints[4]) final; | |
void FillBezier(const BPoint controlPoints[4], const BGradient& gradient) final; | |
void StrokeEllipse(BRect rect) final; | |
void FillEllipse(BRect rect) final; | |
void FillEllipse(BRect rect, const BGradient& gradient) final; | |
void StrokeRoundRect(BRect rect, float xRadius, float yRadius) final; | |
void FillRoundRect(BRect rect, float xRadius, float yRadius) final; | |
void FillRoundRect(BRect rect, float xRadius, float yRadius, const BGradient& gradient) final; | |
void StrokeTriangle(const BPoint points[3], BRect bounds) final; | |
void FillTriangle(const BPoint points[3], BRect bounds) final; | |
void FillTriangle(const BPoint points[3], BRect bounds, const BGradient& gradient) final; | |
void StrokePolygon(BRect bounds, bool closed, int32 count, const BPoint* points) final; | |
void FillPolygon(BRect bounds, int32 count, const BPoint* points) final; | |
void FillPolygon(BRect bounds, int32 count, const BPoint* points, const BGradient& gradient) final; | |
void StrokeShape(const BShape& shape) final; | |
void FillShape(const BShape& shape) final; | |
void FillShape(const BShape& shape, const BGradient& gradient) final; | |
void FillRegion(const BRegion& region) final; | |
void FillRegion(const BRegion& region, const BGradient& gradient) final; | |
void StrokeLineArray(int32 count, const ViewLineArrayInfo* array) final; | |
void DrawString(std::string_view string, BPoint location, const escapement_delta* delta) final; | |
void DrawStringWithOffsets(std::string_view string, int32 locationCount, const BPoint* locations) final; | |
void DrawPicture(Picture* picture, BPoint where) final; | |
protected: | |
Canvas* fBase; | |
Handler* fHandler {}; | |
}; | |
class CanvasRoster { | |
public: | |
virtual ~CanvasRoster() = default; | |
virtual Canvas* NewWindowCanvas(Window* window) = 0; | |
virtual Canvas* NewBitmapCanvas(Bitmap* bitmap) = 0; | |
}; | |
extern CanvasRoster* gCanvasRoster; | |
// #pragma mark - | |
void | |
CanvasState::MovePenTo(BPoint val) | |
{ | |
penLocation = val; | |
dirty |= 1U << CanvasState_penLocation; | |
} | |
void | |
CanvasState::SetPenSize(float val) | |
{ | |
penSize = val; | |
dirty |= 1U << CanvasState_penSize; | |
} | |
void | |
CanvasState::SetHighColor(rgb_color val) | |
{ | |
highColor = val; | |
whichHighColor = B_NO_COLOR; | |
dirty |= (1U << CanvasState_highColor) | (1U << CanvasState_whichHighColor); | |
} | |
void | |
CanvasState::SetHighUIColor(color_which which, float tint) | |
{ | |
whichHighColor = which; | |
whichHighColorTint = tint; | |
dirty |= 1U << CanvasState_whichHighColor; | |
} | |
void | |
CanvasState::SetLowColor(rgb_color val) | |
{ | |
lowColor = val; | |
whichLowColor = B_NO_COLOR; | |
dirty |= (1U << CanvasState_lowColor) | (1U << CanvasState_whichLowColor); | |
} | |
void | |
CanvasState::SetLowUIColor(color_which which, float tint) | |
{ | |
whichLowColor = which; | |
whichLowColorTint = tint; | |
dirty |= 1U << CanvasState_whichLowColor; | |
} | |
void | |
CanvasState::SetPattern(::pattern val) | |
{ | |
pattern = val; | |
dirty |= 1U << CanvasState_pattern; | |
} | |
void | |
CanvasState::SetDrawingMode(drawing_mode val) | |
{ | |
drawingMode = val; | |
dirty |= 1U << CanvasState_drawingMode; | |
} | |
void | |
CanvasState::SetOrigin(BPoint val) | |
{ | |
origin = val; | |
dirty |= 1U << CanvasState_origin; | |
} | |
void | |
CanvasState::SetScale(float val) | |
{ | |
scale = val; | |
dirty |= 1U << CanvasState_scale; | |
} | |
void | |
CanvasState::SetLineMode(cap_mode lineCap, join_mode lineJoin, float miterLimit) | |
{ | |
this->lineCap = lineCap; | |
this->lineJoin = lineJoin; | |
this->miterLimit = miterLimit; | |
dirty |= 1U << CanvasState_lineMode; | |
} | |
void | |
CanvasState::SetFillRule(int32 val) | |
{ | |
fillRule = val; | |
dirty |= 1U << CanvasState_fillRule; | |
} | |
void | |
CanvasState::SetBlendingMode(source_alpha srcAlpha, alpha_function alphaFunc) | |
{ | |
this->alphaSourceMode = srcAlpha; | |
this->alphaFunctionMode = alphaFunc; | |
dirty |= 1U << CanvasState_blendingMode; | |
} | |
void | |
CanvasState::ForceFontAliasing(bool enable) | |
{ | |
fontAntialiasing = enable; | |
dirty |= 1U << CanvasState_fontAntialiasing; | |
} | |
void | |
CanvasState::SetTransform(const BAffineTransform& val) | |
{ | |
transform = val; | |
dirty |= 1U << CanvasState_transform; | |
} | |
inline BRegion& | |
CanvasState::SetClipRegion() | |
{ | |
dirty |= 1U << CanvasState_clipRegion; | |
return clipRegion.emplace(); | |
} | |
inline void | |
CanvasState::ClearClipRegion() | |
{ | |
clipRegion.reset(); | |
dirty |= 1U << CanvasState_clipRegion; | |
} | |
BAffineTransform | |
CanvasState::CombinedTransform() | |
{ | |
BAffineTransform res; | |
res.TranslateBy(origin); | |
res.ScaleBy(scale); | |
res.Multiply(transform); | |
return res; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment