/* $NoKeywords: $ */ /* // // Copyright (c) 1993-2012 Robert McNeel & Associates. All rights reserved. // OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert // McNeel & Associates. // // THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. // ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF // MERCHANTABILITY ARE HEREBY DISCLAIMED. // // For complete openNURBS copyright information see . // //////////////////////////////////////////////////////////////// */ #ifndef OPENNURBS_TEXTRUN_H_INCLUDED #define OPENNURBS_TEXTRUN_H_INCLUDED class ON_CLASS ON_StackedText { public: static const ON_StackedText Empty; public: ON_StackedText() = default; ~ON_StackedText(); ON_StackedText(const ON_StackedText& src); // Sets m_parent_run = nullptr. // You must set m_parent_run after calling operator=(). ON_StackedText& operator=(const ON_StackedText& src); class ON_TextRun* m_top_run = nullptr; class ON_TextRun* m_bottom_run = nullptr; const ON_TextRun* m_parent_run = nullptr; wchar_t m_separator = (wchar_t)ON_UnicodeCodePoint::ON_Slash; enum class StackStyle : unsigned char { kUnset = 0, kHorizontalToScreen = 1, kSlanted = 2, }; static ON_StackedText::StackStyle StackStyleFromUnsigned( unsigned int stack_style_as_unsigned ); private: friend class ON_TextRun; //bool WriteNested( // unsigned int nested_depth, // ON_BinaryArchive& archive // ) const; //bool ReadNested( // unsigned int nested_depth, // ON_BinaryArchive& archive // ); }; // A range of text with all the same attributes class ON_CLASS ON_TextRun { public: static const ON_TextRun Empty; /* Description: ON_TextRun::NewTextRun() gets a text run from an efficiently managed pool. Returns: A pointer to a text run. (never nullptr). */ static ON_TextRun* GetManagedTextRun(); /* Description: ON_TextRun::NewTextRun() gets a text run from an efficiently managed pool and copies src Returns: A pointer to a text run. (never nullptr). */ static ON_TextRun* GetManagedTextRun( const ON_TextRun& src ); /* Description: Return a managed ON_TextRun. */ static bool ReturnManagedTextRun( ON_TextRun* managed_text_run ); /* Returns: True if the memory for this ON_TextRun is managed. It was created by calling ON_TextRun::GetManagedTextRun(). If it is active, then is must be deleted by calling ON_TextRun::ReturnManagedTextRun(); */ bool IsManagedTextRun() const; /* Returns: True if the memory for this ON_TextRun is managed and the text run is active. It was created by calling ON_TextRun::GetManagedTextRun() and should be deleted by calling ON_TextRun::ReturnManagedTextRun(); */ bool IsActiveManagedTextRun() const; public: ON_TextRun() = default; ~ON_TextRun(); ON_TextRun(const ON_TextRun& src); ON_TextRun& operator=(const ON_TextRun& src); private: ON_TextRun(bool bManagedTextRun); public: enum class RunType : unsigned char { kNone = 0, kText = 1, kNewline = 2, kSoftreturn = 3, kParagraph = 4, kColumn = 5, kField = 6, kFieldValue = 7, kFontdef = 8, kHeader = 9, kFonttbl = 10, kColortbl = 11, }; static ON_TextRun::RunType RunTypeFromUnsigned( unsigned int run_type_as_unsigned ); enum class Stacked : unsigned char { kNone = 0, kStacked = 1, kTop = 2, kBottom = 3 }; static ON_TextRun::Stacked StackedFromUnsigned( unsigned int stacked_as_unsigned ); enum class RunDirection : unsigned char { kLtR = 0, kRtL = 1, }; static ON_TextRun::RunDirection RunDirectionFromUnsigned( unsigned int run_direction_as_unsigned ); public: ON_SHA1_Hash TextRunContentHash() const; ON_SHA1_Hash TextRunContentHash( bool bEvaluateFields ) const; void Init( const class ON_Font* managed_font, double height, double stackscale, ON_Color color, bool bold, bool italic, bool underlined, bool strikethrough, bool deletedisplay = true); bool IsText() const; bool IsNewline() const; bool IsColumn() const; bool IsValid() const; RunType Type() const; void SetType(ON_TextRun::RunType); RunDirection FlowDirection() const; Stacked IsStacked() const; void SetStacked(Stacked stacked); void SetStackedOff(); // Set or get the WCS model unit height of the text // not including any annotatition scaling double TextHeight() const; void SetTextHeight(double h); ON_Color Color() const; void SetColor(ON_Color color); void SetFont(const ON_Font* font); const ON_Font* Font() const; // bbox is stored as ON_BoundingBox, but is always 2d. z=0 const ON_BoundingBox& BoundingBox() const; void SetBoundingBox(ON_2dPoint pmin, ON_2dPoint pmax); const ON_2dVector& Offset() const; void SetOffset(ON_2dVector offset); const ON_2dVector& Advance() const; void SetAdvance(ON_2dVector advance); // This returns the scale of m_height / HeightOfI. // It doesn't take into account anything about annotation scaling // This is the scale for converting ON_TextRun bounding boxes and // offsets to basic model units double HeightScale(const ON_Font* font) const; void SetStackFractionHeight(double stackscale); double StackHeightFraction() const; static double DefaultStackFractionHeight(); //bool Write( // ON_BinaryArchive& // ) const; //bool Read( // ON_BinaryArchive& // ); void Get2dCorners(ON_2dPoint corners[4]) const; private: static void SetUnicodeString(ON__UINT32*& dest, size_t count, const ON__UINT32* cp); public: void SetUnicodeString(size_t count, const ON__UINT32* cp); static size_t CodepointCount(const ON__UINT32* cp); // Returns string in m_display_string, which may be the result of parsing text fields void SetDisplayString(const wchar_t* str); // The display string is the TextString() with formulae evaluated. const wchar_t* DisplayString() const; // Returns the string in m_text_string, which is a wchar_t version of the basic text for this run, // and may contain unevaluated field formulae const wchar_t* TextString() const; const ON__UINT32* UnicodeString() const; bool GetGlyphContours( const ON_Font* text_font, bool bSingleStrokeFont, const ON_Xform& text_xform, ON_ClassArray< ON_ClassArray< ON_SimpleArray< ON_Curve* > > >& run_contours ) const; friend class ON_TextBuilder; // Wrap text to a specified width in model space int WrapTextRun( int call_count, int start_char_offset, double width, double &y_offset, double& currentwidth, class ON_TextRunArray& newruns) const; const ON_Font* m_managed_font = nullptr; // Font used to draw, pick, or otherwise evaluate this // ON_TextRun. This pointer is run-time only and must be // set and point to a valid ON_Font for any font related // operations to work. // ON_UUID m_Font_id = ON_nil_uuid; private: ON__UINT32* m_codepoints = nullptr; // Parsed text as UTF32 // Set from m_codepoints when required. // Always use TextString() to get this value mutable ON_wString m_text_string = ON_wString::EmptyString; // Parsed text as wchar_t* // If this string is non-empty, it is valid and can be used // instead of m_codepoints // This string may have unevaluated field definitions - %% mutable ON_wString m_display_string = ON_wString::EmptyString; // Text to display when this is drawn. // If this text has field definitions, m_display_string will have the // evaluation results to display // This string may change often if there are fields to evaluate. mutable ON_SHA1_Hash m_text_run_hash = ON_SHA1_Hash::ZeroDigest; mutable ON_SHA1_Hash m_text_run_display_hash = ON_SHA1_Hash::ZeroDigest; ON_TextRun::Stacked m_text_stacked = ON_TextRun::Stacked::kNone; // 0: Normal text, 1: Run is stacked container, 2: Run is top of stacked fraction, 3: Run is bottom of stacked fraction private: void Internal_ContentChanged() const; public: ON_StackedText* m_stacked_text = nullptr; // pointers to runs for the top and bottom parts ON_Color m_color = ON_Color::UnsetColor; private: ON_TextRun::RunType m_run_type = ON_TextRun::RunType::kNone; ON_TextRun::RunDirection m_direction = ON_TextRun::RunDirection::kLtR; private: // This value of m_managed_status is not copied // 0: Not managed // 1: Managed by GetManagedTextRun() / ReturnManagedTextRun() const unsigned char m_managed_status = 0; unsigned char m_active_status = 0; // 0: active, 1: inactive managed text_run private: double m_run_text_height = 1.0; // (ECS) text height in model units or page units public: ON_2dVector m_offset = ON_2dVector::ZeroVector; // (ECS) offset to lower left of bounding box from ON_TextContent plane origin ON_2dVector m_advance = ON_2dVector::ZeroVector; // (ECS) distance and direction from m_offset to start of next run private: ON_BoundingBox m_bbox = ON_BoundingBox::EmptyBoundingBox; // (ECS) 3d Bounding box oriented to ON_TextContent object's plane (z == 0) with run offset already included public: double m_height_scale = -1.0; // Font HeightOfI / text height - Converts from font units to model units or page units double m_stackscale = 0.7; // fraction for scaling textheight in stacked text // indent and margins are in model units or page units // These apply to Paragraph type runs (m_type == rtParagraph) double m_indent = 0.0; // First line indentation for this paragraph double m_left_margin = 0.0; // left margin in formatting rect for this paragraph double m_right_margin = 0.0; // right margin in formatting rect for this paragraph int m_line_index = -1; // line position in ON_TextContent private: ON__UINT_PTR m_reserved=0; private: friend class ON_StackedText; //bool WriteNested( // unsigned int nested_depth, // ON_BinaryArchive& archive // ) const; //bool ReadNested( // unsigned int nested_depth, // ON_BinaryArchive& archive // ); private: void Internal_Destroy(); void Internal_CopyFrom(const ON_TextRun& src); }; class ON_CLASS ON_TextRunArray : private ON_SimpleArray< ON_TextRun* > { //ON_TextRun*& AppendNew(); //void Append(int, ON_TextRun* const *); //void Append(ON_TextRun* const); public: static const ON_TextRunArray EmptyArray; ON_TextRunArray() = default; // Calls Destroy(true,true) ~ON_TextRunArray(); // Duplicate runs are managed text runs ON_TextRunArray& operator=(const ON_TextRunArray& src); // Duplicate runs are managed text runs ON_TextRunArray(const ON_TextRunArray& src); public: /* Returns: A hash of the information that determines the text content with evaluated fields. */ ON_SHA1_Hash TextRunArrayContentHash() const; /* Parameters: bEvaluateFields - [in] true - hash text with fields evaluated false - hash text with fields unevaluated Returns: A hash of the information that determines the text content without evaluating the fields. */ ON_SHA1_Hash TextRunArrayContentHash( bool bEvaluateFields ) const; // Run must be a managed run or on the heap. // The destructor will return managed runs and delete unmanaged runs. void InsertRun(int i, ON_TextRun*& run); void RemoveRun(int i); // Run must be a managed run or on the heap. // The destructor will return managed runs and delete unmanaged runs. void AppendRun(ON_TextRun*& run); bool Get2dCorners(ON_2dPoint corners[4]) const; const ON_TextRun* operator[](int i) const; ON_TextRun* operator[](int i); int Count() const; unsigned int UnsignedCount() const; ON_TextRun*const* Array() const; /* Parameters: bReturnManagedRuns - [in] True: Managed runs will be returned. False: Caller must explicityly handle managed runs. bDeleteUnmanagedRuns - [in] True: Unmanaged runs are deleted. False: Caller must explicityly handle unmanaged runs. */ void SetTextHeight(double height); private: void Internal_Destroy(); void Internal_CopyFrom(const ON_TextRunArray& src); }; #endif