/* * Copyright (c) 2020-2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * @addtogroup UI_Components * @{ * * @brief Defines UI components such as buttons, texts, images, lists, and progress bars. * * @since 1.0 * @version 1.0 */ /** * @file ui_canvas.h * * @brief Defines the attributes of the canvas component and provides functions for drawing rectangles, * circles, and others. * * @since 1.0 * @version 1.0 */ #ifndef GRAPHIC_LITE_UI_CANVAS_H #define GRAPHIC_LITE_UI_CANVAS_H #include "common/image.h" #include "components/ui_label.h" #include "gfx_utils/diagram/depiction/depict_curve.h" #include "gfx_utils/diagram/depiction/depict_dash.h" #include "gfx_utils/diagram/depiction/depict_stroke.h" #include "gfx_utils/diagram/imagefilter/filter_blur.h" #include "gfx_utils/diagram/rasterizer/rasterizer_scanline_antialias.h" #include "gfx_utils/diagram/scanline/geometry_scanline.h" #include "gfx_utils/diagram/spancolorfill/fill_base.h" #include "gfx_utils/diagram/spancolorfill/fill_gradient.h" #include "gfx_utils/diagram/spancolorfill/fill_gradient_lut.h" #include "gfx_utils/diagram/spancolorfill/fill_interpolator.h" #include "gfx_utils/diagram/spancolorfill/fill_pattern_rgba.h" #include "gfx_utils/diagram/vertexprimitive/geometry_path_storage.h" #include "ui_extend_image_view.h" #include "gfx_utils/file.h" #include "gfx_utils/list.h" #include "gfx_utils/diagram/common/paint.h" namespace OHOS { class RenderBase; /** * @brief Defines a canvas, which is used to draw multiple types of 2D graphs. * * @since 1.0 * @version 1.0 */ class UICanvas : public UIView { public: /** * @brief A constructor used to create a UICanvas instance. * * @since 1.0 * @version 1.0 */ UICanvas() : startPoint_({0, 0}), vertices_(nullptr), path_(nullptr) {} /** * @brief A destructor used to delete the UICanvas instance. * * @since 1.0 * @version 1.0 */ virtual ~UICanvas(); /** * @brief Obtains the view type. * * @return Returns the view type. For details, see {@link UIViewType}. * @since 1.0 * @version 1.0 */ UIViewType GetViewType() const override { return UI_CANVAS; } /** * @brief Clears the entire canvas. * * @since 1.0 * @version 1.0 */ void Clear(); /** * @brief Sets the coordinates of the start point for drawing a line. For example, if startPoint is * set to {50, 50}, the line is drawn from this set of coordinates on the canvas. * * @param startPoint Indicates the coordinates of the start point. * @see GetStartPosition * @since 1.0 * @version 1.0 */ void SetStartPosition(const Point& startPoint) { startPoint_ = startPoint; } /** * @brief Obtains the coordinates of the start point of a line. * * @return Returns the coordinates of the start point. * @see SetStartPosition * @since 1.0 * @version 1.0 */ const Point& GetStartPosition() const { return startPoint_; } /** * @brief Draws a straight line. * * If {@link SetStartPosition} is not used to set the coordinates of the start point of the line, the drawing * starts from the end point of the last line. * * @param endPoint Indicates the end point of the straight line. * @param paint Indicates the straight line style. For details, see {@link Paint}. * @since 1.0 * @version 1.0 */ void DrawLine(const Point& endPoint, const Paint& paint); /** * @brief Draws a straight line from the coordinates of the start point. * * @param startPoint Indicates the coordinates of the start point. * @param endPoint Indicates the coordinates of the end point. * @param paint Indicates the straight line style. For details, see {@link Paint}. * @since 1.0 * @version 1.0 */ void DrawLine(const Point& startPoint, const Point& endPoint, const Paint& paint); /** * @brief Draws a cubic Bezier curve. * * If {@link SetStartPosition} is not used to set the coordinates of the start point of the curve, * the drawing starts from the end point of the last line. * Currently, the opacity cannot be set, and the maximum line width is 3. * * @param control1 Indicates the coordinates of the first control point of the cubic Bezier curve. * @param control2 Indicates the coordinates of the second control point of the cubic Bezier curve. * @param endPoint Indicates the coordinates of the end point of the cubic Bezier curve. * @param paint Indicates the curve style. For details, see {@link Paint}. * @since 1.0 * @version 1.0 */ void DrawCurve(const Point& control1, const Point& control2, const Point& endPoint, const Paint& paint); /** * @brief Draws a cubic Bezier curve from the start point coordinates. * * Currently, the opacity cannot be set, and the maximum line width is 3. * * @param startPoint Indicates the coordinates of the start point of the cubic Bezier curve. * @param control1 Indicates the coordinates of the first control point of the cubic Bezier curve. * @param control2 Indicates the coordinates of the second control point of the cubic Bezier curve. * @param endPoint Indicates the coordinates of the end point of the cubic Bezier curve. * @param paint Indicates the curve style. For details, see {@link Paint}. * @since 1.0 * @version 1.0 */ void DrawCurve(const Point& startPoint, const Point& control1, const Point& control2, const Point& endPoint, const Paint& paint); /** * @brief Draws a rectangle. * * @param startPoint Indicates the coordinates of the point at the upper left corner of the rectangle. * @param height Indicates the height of the rectangle. * @param width Indicates the width of the rectangle. * @param paint Indicates the rectangle style. For details, see {@link Paint}. * @since 1.0 * @version 1.0 */ void DrawRect(const Point& startPoint, int16_t height, int16_t width, const Paint& paint); #if defined(ENABLE_CANVAS_EXTEND) && ENABLE_CANVAS_EXTEND /** * @brief Draws a rectangular path with no fill. * @param startPoint starting point * @param height * @param width * @param paint paint brush */ void StrokeRect(const Point& startPoint, int16_t height, int16_t width, const Paint& paint); /** * @brief Clears pixels within a rectangle * @param startPoint starting point * @param height * @param width */ void ClearRect(const Point& startPoint, int16_t height, int16_t width); #endif /** * @brief Draws a circle. * * @param center Indicates the coordinates of the circle center. * @param radius Indicates the radius of the circle. * @param paint Indicates the circle style. For details, see {@link Paint}. * @since 1.0 * @version 1.0 */ void DrawCircle(const Point& center, uint16_t radius, const Paint& paint); /** * @brief Draws a sector. * * When the start angle is smaller than the end angle, the sector is drawn clockwise. * Otherwise, the sector is drawn counterclockwise. * * @param center Indicates the coordinates of the sector's center. * @param radius Indicates the radius of the sector. * @param startAngle Indicates the start angle of the sector. Value 0 indicates the 12-o'clock direction, * and 90 indicates the 3-o'clock direction. * @param endAngle Indicates the end angle of the sector. Value 0 indicates the 12-o'clock direction, * and 90 indicates the 3-o'clock direction. * @param paint Indicates the sector style. For details, see {@link Paint}. * @since 1.0 * @version 1.0 */ void DrawSector(const Point& center, uint16_t radius, int16_t startAngle, int16_t endAngle, const Paint& paint); /** * @brief Draws an arc. * * Only stroke is supported. \n * When the start angle is smaller than the end angle, the sector is drawn clockwise. * Otherwise, the sector is drawn counterclockwise. \n * * @param center Indicates the coordinates of the arc's center. * @param radius Indicates the radius of the arc. * @param startAngle Indicates the start angle of the arc. Value 0 indicates the 12-o'clock direction, * and 90 indicates the 3-o'clock direction. * @param endAngle Indicates the end angle of the arc. Value 0 indicates the 12-o'clock direction, * and 90 indicates the 3-o'clock direction. * @param paint Indicates the arc style. For details, see {@link Paint}. * @since 1.0 * @version 1.0 */ void DrawArc(const Point& center, uint16_t radius, int16_t startAngle, int16_t endAngle, const Paint& paint); #if defined(GRAPHIC_ENABLE_DRAW_IMAGE_FLAG) && GRAPHIC_ENABLE_DRAW_IMAGE_FLAG /** * @brief Draws an image. * * @param startPoint Indicates the coordinates of the start point. * @param image Indicates the pointer to the image source. * @param paint Indicates the image style. For details, see {@link Paint}. * @since 1.0 * @version 1.0 */ void DrawImage(const Point& startPoint, const char* image, const Paint& paint); void DrawImage(const Point& startPoint, const char* image, const Paint& paint, int16_t width, int16_t height); #endif /** * @brief Defines the font style. */ struct FontStyle : public HeapBase { /** Text direction. For details, see {@link UITextLanguageDirect}. */ UITextLanguageDirect direct; /** Text alignment mode. For details, see {@link UITextLanguageAlignment}. */ UITextLanguageAlignment align; /** Font size */ uint8_t fontSize; /** Letter-spacing */ int16_t letterSpace; /** Font name */ const char* fontName; }; struct DrawCmd : public HeapBase { Paint paint; void* param; void (*DrawGraphics)(BufferInfo&, void*, const Paint&, const Rect&, const Rect&, const Style&); void (*DeleteParam)(void*); }; /** * @brief Draws text. * * Only fill is supported. \n * If the text length exceeds the value of maxWidth, the text will be truncated. \n * * @param startPoint Indicates the coordinates of the start point. * @param text Indicates the pointer to the text content. * @param maxWidth Indicates the maximum width of the text that can be displayed. If the maximum width is * exceeded, the text is truncated. * @param fontStyle Indicates the text layout and font style. For details, see {@link FontStyle}. * @param paint Indicates the text style. For details, see {@link Paint}. * @since 1.0 * @version 1.0 */ void DrawLabel(const Point& startPoint, const char* text, uint16_t maxWidth, const FontStyle& fontStyle, const Paint& paint); /** * @brief Creates a path. * * A round corner can be used to join two lines. Currently, miter and bevel joints are not supported. * To draw this path, you need to call {@link DrawPath}. * * @since 3.0 * @version 5.0 */ void BeginPath(); /** * @brief Moves the start point of this path to a specified point. * * @param point Indicates the specified point to move to. * @since 3.0 * @version 5.0 */ void MoveTo(const Point& point); /** * @brief Creates a straight line from the end point of this path to a specified point. * * @param point Indicates the coordinates of the specified point. * @since 3.0 * @version 5.0 */ void LineTo(const Point& point); /** * @brief Creates an arc path. * * @param center Indicates the coordinates of the arc's center point. * @param radius Indicates the radius of the arc. * @param startAngle Indicates the start angle of the arc. * The value 0 indicates the 12-o'clock direction, * and 90 indicates the 3-o'clock direction. * @param endAngle Indicates the end angle of the arc. * The value 0 indicates the 12-o'clock direction, * and 90 indicates the 3-o'clock direction. * @since 3.0 * @version 5.0 */ void ArcTo(const Point& center, uint16_t radius, int16_t startAngle, int16_t endAngle); /** * @brief Creates a rectangular path. * * @param point Indicates the coordinates of the rectangle's upper left corner. * @param height Indicates the height of the rectangle. * @param width Indicates the width of the rectangle. * @since 3.0 * @version 5.0 */ void AddRect(const Point& point, int16_t height, int16_t width); /** * @brief Closes this path. * * @since 3.0 * @version 5.0 */ void ClosePath(); /** * @brief Draws this path. * * @param paint Indicates the path style. For details, see {@link Paint}. * @since 3.0 * @version 5.0 */ void DrawPath(const Paint& paint); #if defined(ENABLE_CANVAS_EXTEND) && ENABLE_CANVAS_EXTEND /** * @brief Fill polygon path * @param paint fill paint * @since 3.0 * @version 5.0 */ void FillPath(const Paint& paint); #endif #if defined(GRAPHIC_ENABLE_DRAW_TEXT_FLAG) && GRAPHIC_ENABLE_DRAW_TEXT_FLAG /* Draw text on canvas */ void StrokeText(const char* text, const Point& point, const FontStyle& fontStyle, const Paint& paint); #endif /* Returns an object containing the specified text width */ Point MeasureText(const char* text, const FontStyle& fontStyle); /* Save history status */ void Save(Paint paint) { paintStack_.PushBack(paint); } /** * @brief Restore to last historical state * @return Returns the last paint value. * @since 3.0 * @version 5.0 */ Paint Restore() { Paint paint; if (paintStack_.IsEmpty()) { return paint; } paint = paintStack_.Back(); paintStack_.PopBack(); return paint; } #if defined(ENABLE_CANVAS_EXTEND) && ENABLE_CANVAS_EXTEND void OnBlendDraw(BufferInfo& gfxDstBuffer, const Rect& trunc); #endif void OnDraw(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea) override; static void BlendRaster(const Paint& paint, void* param, RasterizerScanlineAntialias& blendRasterizer, RasterizerScanlineAntialias& rasterizer, RenderBase& renBase, TransAffine& transform, SpanBase& spanGen, const Rect& rect, bool isStroke); static void DeleteImageParam(void* param); static void DeletePathParam(void* param); protected: constexpr static uint8_t MAX_CURVE_WIDTH = 3; struct LineParam : public HeapBase { Point start; Point end; }; struct CurveParam : public HeapBase { Point start; Point control1; Point control2; Point end; }; struct RectParam : public HeapBase { Point start; int16_t height; int16_t width; }; struct CircleParam : public HeapBase { Point center; uint16_t radius; }; struct ArcParam : public HeapBase { Point center; uint16_t radius; int16_t startAngle; int16_t endAngle; }; enum PathCmd { CMD_MOVE_TO, CMD_LINE_TO, CMD_ARC, CMD_CLOSE, }; class UICanvasPath : public HeapBase { public: UICanvasPath() : startPos_({ 0, 0 }), strokeCount_(0) {}; ~UICanvasPath(); List points_; List cmd_; List arcParam_; Point startPos_; uint16_t strokeCount_; }; #if (!(defined(ENABLE_CANVAS_EXTEND) && ENABLE_CANVAS_EXTEND)) struct PathParam : public HeapBase { UICanvasPath* path; uint16_t count; }; struct ImageParam : public HeapBase { Point start; uint16_t height; uint16_t width; Image* image; }; #endif struct TextParam : public HeapBase { const char* text; Point position; Color32 fontColor; uint8_t fontOpa; FontStyle fontStyle; Text* textComment; TextParam() : text(nullptr), position({0, 0}), fontOpa(0) { fontColor.full = 0; fontStyle.direct = UITextLanguageDirect::TEXT_DIRECT_LTR; fontStyle.align = UITextLanguageAlignment::TEXT_ALIGNMENT_LEFT; fontStyle.fontSize = 0; fontStyle.letterSpace = 0; fontStyle.fontName = nullptr; textComment = new Text; } ~TextParam() { if (textComment) { delete textComment; textComment = nullptr; } }; }; Point startPoint_; UICanvasVertices* vertices_; UICanvasPath* path_; List drawCmdList_; // Save historical modification information of paint List paintStack_; static BufferInfo* gfxMapBuffer_; static void DeleteLineParam(void* param) { LineParam* lineParam = static_cast(param); delete lineParam; } static void DeleteCurveParam(void* param) { CurveParam* curveParam = static_cast(param); delete curveParam; } static void DeleteRectParam(void* param) { RectParam* rectParam = static_cast(param); delete rectParam; } static void DeleteCircleParam(void* param) { CircleParam* circleParam = static_cast(param); delete circleParam; } static void DeleteArcParam(void* param) { ArcParam* arcParam = static_cast(param); delete arcParam; } static void DeleteLabel(void* param) { UILabel* label = static_cast(param); delete label; } static void DeleteImageView(void* param) { UIExtendImageView* imageView = static_cast(param); delete imageView; } static void DeleteTextParam(void* param) { TextParam* textParam = static_cast(param); delete textParam; } static void DoDrawLine(BufferInfo& gfxDstBuffer, void* param, const Paint& paint, const Rect& rect, const Rect& invalidatedArea, const Style& style); static void DoDrawCurve(BufferInfo& gfxDstBuffer, void* param, const Paint& paint, const Rect& rect, const Rect& invalidatedArea, const Style& style); static void DoDrawRect(BufferInfo& gfxDstBuffer, void* param, const Paint& paint, const Rect& rect, const Rect& invalidatedArea, const Style& style); static void DoFillRect(BufferInfo& gfxDstBuffer, void* param, const Paint& paint, const Rect& rect, const Rect& invalidatedArea, const Style& style); static void DoDrawCircle(BufferInfo& gfxDstBuffer, void* param, const Paint& paint, const Rect& rect, const Rect& invalidatedArea, const Style& style); static void DoDrawArc(BufferInfo& gfxDstBuffer, void* param, const Paint& paint, const Rect& rect, const Rect& invalidatedArea, const Style& style); #if defined(GRAPHIC_ENABLE_DRAW_IMAGE_FLAG) && GRAPHIC_ENABLE_DRAW_IMAGE_FLAG static void DoDrawImage(BufferInfo& gfxDstBuffer, void* param, const Paint& paint, const Rect& rect, const Rect& invalidatedArea, const Style& style); #endif static void DoDrawLabel(BufferInfo& gfxDstBuffer, void* param, const Paint& paint, const Rect& rect, const Rect& invalidatedArea, const Style& style); static void DoDrawPath(BufferInfo& gfxDstBuffer, void* param, const Paint& paint, const Rect& rect, const Rect& invalidatedArea, const Style& style); static void GetAbsolutePosition(const Point& prePoint, const Rect& rect, const Style& style, Point& point); static void DoDrawLineJoin(BufferInfo& gfxDstBuffer, const Point& center, const Rect& invalidatedArea, const Paint& paint); static void DoFillPath(BufferInfo& gfxDstBuffer, void* param, const Paint& paint, const Rect& rect, const Rect& invalidatedArea, const Style& style); static void BlitMapBuffer(BufferInfo &gfxDstBuffer, BufferInfo& gfxMapBuffer, Rect& textRect, TransformMap& transMap, const Rect& invalidatedArea); #if defined(GRAPHIC_ENABLE_DRAW_TEXT_FLAG) && GRAPHIC_ENABLE_DRAW_TEXT_FLAG static void DoDrawText(BufferInfo& gfxDstBuffer, void* param, const Paint& paint, const Rect& rect, const Rect& invalidatedArea, const Style& style); #endif /** * Assembly parameter setting lineweight,LineCap,LineJoin */ template static void LineStyleCalc(DepictStroke& strokeLineStyle, const Paint& paint) { strokeLineStyle.SetWidth(paint.GetStrokeWidth()); // Line style related #if defined(GRAPHIC_ENABLE_LINECAP_FLAG) && GRAPHIC_ENABLE_LINECAP_FLAG strokeLineStyle.SetLineCap(paint.GetLineCap()); #endif #if defined(GRAPHIC_ENABLE_LINEJOIN_FLAG) && GRAPHIC_ENABLE_LINEJOIN_FLAG strokeLineStyle.SetLineJoin(paint.GetLineJoin()); if (paint.GetMiterLimit() > 0) { strokeLineStyle.SetMiterLimit(paint.GetMiterLimit()); } #endif }; static bool IsSoild(const Paint& paint) { if (paint.GetStyle() == Paint::STROKE_STYLE || paint.GetStyle() == Paint::FILL_STYLE || paint.GetStyle() == Paint::STROKE_FILL_STYLE) { return true; } return false; } void DrawRectSetCmd(const Point& startPoint, int16_t height, int16_t width, const Paint& paint, Paint::PaintStyle paintStyle); static void InitGfxMapBuffer(const BufferInfo& srcBuff, const Rect& rect); static BufferInfo* UpdateMapBufferInfo(const BufferInfo& srcBuff, const Rect& rect); static void DestroyMapBufferInfo(); void SetArcParamInfo(const Point& center, uint16_t radius, int16_t startAngle, int16_t endAngle); #if defined(ENABLE_CANVAS_EXTEND) && ENABLE_CANVAS_EXTEND void SetDrawLinePath(const Point& startPoint, int16_t height, int16_t width, const Paint& paint); #endif }; } // namespace OHOS #endif // GRAPHIC_LITE_UI_CANVAS_H