//------------------------------------------------------------------------------ // Copyright (c) 2001-2005, Haiku, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. // // File Name: LayerData.cpp // Author: DarkWyrm // Adi Oanca // Stephan Aßmus // Description: Data classes for working with BView states and draw parameters // //------------------------------------------------------------------------------ #include #include #include "LinkMsgReader.h" #include "LinkMsgSender.h" #include "LayerData.h" // constructor DrawData::DrawData() : fOrigin(0.0, 0.0), fScale(1.0), fClippingRegion(NULL), fHighColor(0, 0, 0, 255), fLowColor(255, 255, 255, 255), fPattern(kSolidHigh), fDrawingMode(B_OP_COPY), fAlphaSrcMode(B_PIXEL_ALPHA), fAlphaFncMode(B_ALPHA_OVERLAY), fPenLocation(0.0, 0.0), fPenSize(1.0), fFont(), fFontAntiAliasing(true), fLineCapMode(B_BUTT_CAP), fLineJoinMode(B_BEVEL_JOIN), fMiterLimit(B_DEFAULT_MITER_LIMIT) { if (fontserver && fontserver->GetSystemPlain()) fFont = *(fontserver->GetSystemPlain()); fEscapementDelta.space = 0; fEscapementDelta.nonspace = 0; fUnscaledFontSize = fFont.Size(); } // copy constructor DrawData::DrawData(const DrawData& from) : fClippingRegion(NULL) { *this = from; } // destructor DrawData::~DrawData() { delete fClippingRegion; } // operator= DrawData& DrawData::operator=(const DrawData& from) { fOrigin = from.fOrigin; fScale = from.fScale; if (from.fClippingRegion) { SetClippingRegion(*(from.fClippingRegion)); } else { delete fClippingRegion; fClippingRegion = NULL; } fHighColor = from.fHighColor; fLowColor = from.fLowColor; fPattern = from.fPattern; fDrawingMode = from.fDrawingMode; fAlphaSrcMode = from.fAlphaSrcMode; fAlphaFncMode = from.fAlphaFncMode; fPenLocation = from.fPenLocation; fPenSize = from.fPenSize; fFont = from.fFont; fFontAntiAliasing = from.fFontAntiAliasing; fEscapementDelta = from.fEscapementDelta; fLineCapMode = from.fLineCapMode; fLineJoinMode = from.fLineJoinMode; fMiterLimit = from.fMiterLimit; fUnscaledFontSize = from.fUnscaledFontSize; return *this; } // SetOrigin void DrawData::SetOrigin(const BPoint& origin) { fOrigin = origin; } // OffsetOrigin void DrawData::OffsetOrigin(const BPoint& offset) { fOrigin += offset; } // SetScale void DrawData::SetScale(float scale) { if (fScale != scale) { fScale = scale; // update font size // (pen size is currently calulated on the fly) fFont.SetSize(fUnscaledFontSize * fScale); } } // SetClippingRegion void DrawData::SetClippingRegion(const BRegion& region) { if (region.Frame().IsValid()) { if (fClippingRegion) *fClippingRegion = region; else fClippingRegion = new BRegion(region); } else { delete fClippingRegion; fClippingRegion = NULL; } } // SetHighColor void DrawData::SetHighColor(const RGBColor& color) { fHighColor = color; } // SetLowColor void DrawData::SetLowColor(const RGBColor& color) { fLowColor = color; } // SetPattern void DrawData::SetPattern(const Pattern& pattern) { fPattern = pattern; } // SetDrawingMode void DrawData::SetDrawingMode(drawing_mode mode) { fDrawingMode = mode; } // SetBlendingMode void DrawData::SetBlendingMode(source_alpha srcMode, alpha_function fncMode) { fAlphaSrcMode = srcMode; fAlphaFncMode = fncMode; } // SetPenLocation void DrawData::SetPenLocation(const BPoint& location) { // TODO: Needs to be in local coordinate system! // There is going to be some work involved in // other parts of app_server... fPenLocation = location; } // PenLocation const BPoint& DrawData::PenLocation() const { // TODO: See above return fPenLocation; } // SetPenSize void DrawData::SetPenSize(float size) { fPenSize = size; } // PenSize // * returns the scaled pen size float DrawData::PenSize() const { float penSize = fPenSize * fScale; // NOTE: As documented in the BeBook, // pen size is never smaller than 1.0. // This is supposed to be the smallest // possible device size. if (penSize < 1.0) penSize = 1.0; return penSize; } // SetFont // * sets the font to be already scaled by fScale void DrawData::SetFont(const ServerFont& font, uint32 flags) { if (flags == B_FONT_ALL) { fFont = font; fUnscaledFontSize = font.Size(); fFont.SetSize(fUnscaledFontSize * fScale); } else { // family & style if (flags & B_FONT_FAMILY_AND_STYLE) fFont.SetFamilyAndStyle(font.GetFamilyAndStyle()); // size if (flags & B_FONT_SIZE) { fUnscaledFontSize = font.Size(); fFont.SetSize(fUnscaledFontSize * fScale); } // shear if (flags & B_FONT_SHEAR) fFont.SetShear(font.Shear()); // rotation if (flags & B_FONT_ROTATION) fFont.SetRotation(font.Rotation()); // spacing if (flags & B_FONT_SPACING) fFont.SetSpacing(font.Spacing()); // encoding if (flags & B_FONT_ENCODING) fFont.SetEncoding(font.Encoding()); // face if (flags & B_FONT_FACE) fFont.SetFace(font.Face()); // flags if (flags & B_FONT_FLAGS) fFont.SetFlags(font.Flags()); } } // SetFontAntiAliasing void DrawData::SetFontAntiAliasing(bool antiAliasing) { fFontAntiAliasing = antiAliasing; } // SetEscapementDelta void DrawData::SetEscapementDelta(escapement_delta delta) { fEscapementDelta = delta; } // SetLineCapMode void DrawData::SetLineCapMode(cap_mode mode) { fLineCapMode = mode; } // SetLineJoinMode void DrawData::SetLineJoinMode(join_mode mode) { fLineJoinMode = mode; } // SetMiterLimit void DrawData::SetMiterLimit(float limit) { fMiterLimit = limit; } //----------------------------LayerData---------------------- // #pragmamark - // constructpr LayerData::LayerData() : DrawData(), prevState(NULL) { } // LayerData LayerData::LayerData(const LayerData &data) { fClippingRegion = NULL; *this = data; } // destructor LayerData::~LayerData(void) { delete prevState; } // operator= LayerData& LayerData::operator=(const LayerData& from) { DrawData::operator=(from); prevState = from.prevState; return *this; } // PrintToStream void LayerData::PrintToStream() const { printf("\t Origin: (%.1f, %.1f)\n", fOrigin.x, fOrigin.y); printf("\t Scale: %.2f\n", fScale); printf("\t Pen Location and Size: (%.1f, %.1f) - %.2f (%.2f)\n", fPenLocation.x, fPenLocation.y, PenSize(), fPenSize); printf("\t HighColor: "); fHighColor.PrintToStream(); printf("\t LowColor: "); fLowColor.PrintToStream(); printf("\t Pattern: %llu\n", fPattern.GetInt64()); printf("\t DrawMode: %lu\n", (uint32)fDrawingMode); printf("\t AlphaSrcMode: %ld\t AlphaFncMode: %ld\n", (int32)fAlphaSrcMode, (int32)fAlphaFncMode); printf("\t LineCap: %d\t LineJoin: %d\t MiterLimit: %.2f\n", (int16)fLineCapMode, (int16)fLineJoinMode, fMiterLimit); if (fClippingRegion) fClippingRegion->PrintToStream(); printf("\t ===== Font Data =====\n"); printf("\t Style: CURRENTLY NOT SET\n"); // ??? printf("\t Size: %.1f (%.1f)\n", fFont.Size(), fUnscaledFontSize); printf("\t Shear: %.2f\n", fFont.Shear()); printf("\t Rotation: %.2f\n", fFont.Rotation()); printf("\t Spacing: %ld\n", fFont.Spacing()); printf("\t Encoding: %ld\n", fFont.Encoding()); printf("\t Face: %d\n", fFont.Face()); printf("\t Flags: %lu\n", fFont.Flags()); } // ReadFontFromLink void LayerData::ReadFontFromLink(BPrivate::LinkReceiver& link) { uint16 mask; link.Read(&mask); if (mask & B_FONT_FAMILY_AND_STYLE) { uint32 fontID; link.Read((int32*)&fontID); fFont.SetFamilyAndStyle(fontID); } if (mask & B_FONT_SIZE) { float size; link.Read(&size); fFont.SetSize(size); } if (mask & B_FONT_SHEAR) { float shear; link.Read(&shear); fFont.SetShear(shear); } if (mask & B_FONT_ROTATION) { float rotation; link.Read(&rotation); fFont.SetRotation(rotation); } if (mask & B_FONT_SPACING) { uint8 spacing; link.Read(&spacing); fFont.SetSpacing(spacing); } if (mask & B_FONT_ENCODING) { uint8 encoding; link.Read((uint8*)&encoding); fFont.SetEncoding(encoding); } if (mask & B_FONT_FACE) { uint16 face; link.Read(&face); fFont.SetFace(face); } if (mask & B_FONT_FLAGS) { uint32 flags; link.Read(&flags); fFont.SetFlags(flags); } } // ReadFromLink void LayerData::ReadFromLink(BPrivate::LinkReceiver& link) { rgb_color highColor; rgb_color lowColor; pattern patt; link.Read(&fPenLocation); link.Read(&fPenSize); link.Read(&highColor, sizeof(rgb_color)); link.Read(&lowColor, sizeof(rgb_color)); link.Read(&patt, sizeof(pattern)); link.Read((int8*)&fDrawingMode); link.Read(&fOrigin); link.Read((int8*)&fLineJoinMode); link.Read((int8*)&fLineCapMode); link.Read(&fMiterLimit); link.Read((int8*)&fAlphaSrcMode); link.Read((int8*)&fAlphaFncMode); link.Read(&fScale); link.Read(&fFontAntiAliasing); // TODO: ahm... which way arround? fFontAntiAliasing = !fFontAntiAliasing; fHighColor = highColor; fLowColor = lowColor; fPattern = patt; // read clipping int32 clipRectCount; link.Read(&clipRectCount); BRegion region; if (clipRectCount > 0) { BRect rect; for (int32 i = 0; i < clipRectCount; i++) { link.Read(&rect); region.Include(rect); } } SetClippingRegion(region); } // WriteToLink void LayerData::WriteToLink(BPrivate::LinkSender& link) const { rgb_color hc = fHighColor.GetColor32(); rgb_color lc = fLowColor.GetColor32(); // Attach font state link.Attach(fFont.GetFamilyAndStyle()); link.Attach(fFont.Size()); link.Attach(fFont.Shear()); link.Attach(fFont.Rotation()); link.Attach(fFont.Spacing()); link.Attach(fFont.Encoding()); link.Attach(fFont.Face()); link.Attach(fFont.Flags()); // Attach view state link.Attach(fPenLocation); link.Attach(fPenSize); link.Attach(&hc, sizeof(rgb_color)); link.Attach(&lc, sizeof(rgb_color)); link.Attach(fPattern.GetInt64()); link.Attach(fOrigin); link.Attach((uint8)fDrawingMode); link.Attach((uint8)fLineCapMode); link.Attach((uint8)fLineJoinMode); link.Attach(fMiterLimit); link.Attach((uint8)fAlphaSrcMode); link.Attach((uint8)fAlphaFncMode); link.Attach(fScale); link.Attach(!fFontAntiAliasing); int32 clippingRectCount = fClippingRegion ? fClippingRegion->CountRects() : 0; link.Attach(clippingRectCount); if (fClippingRegion) { for (int i = 0; i < clippingRectCount; i++) link.Attach(fClippingRegion->RectAt(i)); } }