mirror of
https://github.com/mcneel/opennurbs.git
synced 2026-03-04 14:09:41 +08:00
Co-authored-by: Andrew Le Bihan <andy@mcneel.com> Co-authored-by: Dale Fugier <dale@mcneel.com> Co-authored-by: Dale Lear <dalelear@mcneel.com> Co-authored-by: Greg Arden <greg@mcneel.com> Co-authored-by: Jussi <jussi@mcneel.com> Co-authored-by: Lowell <lowell@mcneel.com> Co-authored-by: Rajaa Issa <rajaa@mcneel.com> Co-authored-by: Steve Baer <steve@mcneel.com> Co-authored-by: alain <alain@mcneel.com> Co-authored-by: chuck <chuck@mcneel.com> Co-authored-by: piac <giulio@mcneel.com>
443 lines
13 KiB
C++
443 lines
13 KiB
C++
|
|
/* $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 <http://www.opennurbs.org>.
|
|
//
|
|
////////////////////////////////////////////////////////////////
|
|
*/
|
|
|
|
#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 - %<field_name>%
|
|
|
|
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
|