#include "HWPRecordCharShape.h" #include "../HWPElements/HWPRecordFaceName.h" #include "../Common/NodeNames.h" namespace HWP { EAccent GetAccent(int nValue) { SWITCH(EAccent, nValue) { DEFAULT(EAccent::NONE); CASE(EAccent::DOT); CASE(EAccent::RING); CASE(EAccent::CARON); CASE(EAccent::TILDE); CASE(EAccent::ARAEA); CASE(EAccent::TWOARAEA); } } //Всречается только в hwpx EAccent GetAccent(const std::string& sValue) { if (sValue.empty() || "NONE" == sValue) return EAccent::NONE; if ("DOT" == sValue) return EAccent::DOT; if ("RING" == sValue) return EAccent::RING; if ("CARON" == sValue) return EAccent::CARON; if ("TILDE" == sValue) return EAccent::TILDE; if ("ARAEA" == sValue) return EAccent::ARAEA; if ("TWOARAEA" == sValue) return EAccent::TWOARAEA; return EAccent::NONE; } ELang GetLang(int nValue) { switch (static_cast(nValue)) { case ELang::HANGUL: case ELang::LATIN: case ELang::HANJA: case ELang::JAPANESE: case ELang::OTHER: case ELang::SYMBOL: case ELang::USER: case ELang::MAX: return static_cast(nValue); default: return ELang::HANGUL; } } EUnderline GetUnderline(int nValue) { SWITCH(EUnderline, nValue) { DEFAULT(EUnderline::NONE); CASE(EUnderline::BOTTOM); CASE(EUnderline::CENTER); CASE(EUnderline::TOP); } } EUnderline GetUnderline(const std::string& sValue, EHanType eType) { if (sValue.empty() || GetValueName(EValue::None, eType) == sValue) return EUnderline::NONE; if (GetValueName(EValue::Bottom, eType) == sValue) return EUnderline::BOTTOM; if (GetValueName(EValue::Center, eType) == sValue) return EUnderline::CENTER; if (GetValueName(EValue::Top, eType) == sValue) return EUnderline::TOP; return EUnderline::NONE; } EShadow GetShadow(int nValue) { SWITCH(EShadow, nValue) { DEFAULT(EShadow::NONE); CASE(EShadow::DISCRETE); CASE(EShadow::CONTINUOUS); } } EShadow GetShadow(const std::string& sValue, EHanType eType) { if (sValue.empty() || GetValueName(EValue::None, eType) == sValue) return EShadow::NONE; if (GetValueName(EValue::Discrete, eType) == sValue) return EShadow::DISCRETE; if (GetValueName(EValue::Continuous, eType) == sValue) return EShadow::CONTINUOUS; } void CHWPRecordCharShape::ReadContainerData(CXMLReader& oReader, short arValues[], int nDefaultValue) { for (unsigned int unIndex = 0; unIndex < (int)ELang::MAX; ++unIndex) arValues[unIndex] = nDefaultValue; START_READ_ATTRIBUTES(oReader) { TO_LOWER(sAttributeName); if ("hangul" == sAttributeName) arValues[(int)ELang::HANGUL] = oReader.GetInt(); else if ("latin" == sAttributeName) arValues[(int)ELang::LATIN] = oReader.GetInt(); else if ("hanja" == sAttributeName) arValues[(int)ELang::HANJA] = oReader.GetInt(); else if ("japanese" == sAttributeName) arValues[(int)ELang::JAPANESE] = oReader.GetInt(); else if ("other" == sAttributeName) arValues[(int)ELang::OTHER] = oReader.GetInt(); else if ("symbol" == sAttributeName) arValues[(int)ELang::SYMBOL] = oReader.GetInt(); else if ("user" == sAttributeName) arValues[(int)ELang::USER] = oReader.GetInt(); } END_READ_ATTRIBUTES(oReader) } CHWPRecordCharShape::CHWPRecordCharShape(CHWPDocInfo& oDocInfo, int nTagNum, int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion) : CHWPRecord(nTagNum, nLevel, nSize), m_pParent(&oDocInfo) { oBuffer.SavePosition(); for (int nIndex = 0; nIndex < MAX_ELEMENTS; ++nIndex) { short shFontID; oBuffer.ReadShort(shFontID); const CHWPRecordFaceName* pFaceName = dynamic_cast(m_pParent->GetFaceName(shFontID)); if (nullptr != pFaceName) m_arFontNames[nIndex] = pFaceName->GetFaceName(); } #define READ_ELEMENT(_type) (_type)(oBuffer[0] & 0x00FF); oBuffer.Skip(1) for (int nIndex = 0; nIndex < MAX_ELEMENTS; ++nIndex) { m_arRatios[nIndex] = READ_ELEMENT(short); } for (int nIndex = 0; nIndex < MAX_ELEMENTS; ++nIndex) { m_arSpacings[nIndex] = READ_ELEMENT(HWP_BYTE); } for (int nIndex = 0; nIndex < MAX_ELEMENTS; ++nIndex) { m_arRelSizes[nIndex] = READ_ELEMENT(short); } for (int nIndex = 0; nIndex < MAX_ELEMENTS; ++nIndex) { m_arCharOffset[nIndex] = READ_ELEMENT(HWP_BYTE); } oBuffer.ReadInt(m_nHeight); int nAttrBits; oBuffer.ReadInt(nAttrBits); // Attributes m_bItalic = CHECK_FLAG(nAttrBits, 0x01); m_bBold = CHECK_FLAG(nAttrBits, 0x02); m_eUnderline = GetUnderline((nAttrBits >> 2) & 0x03); m_eUnderLineShape = GetLineStyle1((nAttrBits >> 4) & 0x0F); m_eOutline = GetLineStyle3((nAttrBits >> 8) & 0x07); m_eShadow = GetShadow((nAttrBits >> 11) & 0x03); m_bEmboss = CHECK_FLAG(nAttrBits, 0x2000); m_bEngrave = CHECK_FLAG(nAttrBits, 0x4000); m_bSuperScript = CHECK_FLAG(nAttrBits, 0x8000); m_bSubScript = CHECK_FLAG(nAttrBits, 0xF000); m_chStrikeOut = (HWP_BYTE)((nAttrBits >> 18) & 0x07); m_eSymMark = GetAccent((nAttrBits >> 21) & 0x0F); m_bUseFontSpace = CHECK_FLAG(nAttrBits, 0x2000000); m_eStrikeOutShape = GetLineStyle2((nAttrBits >> 26) & 0x0F); m_bUseKerning = CHECK_FLAG(nAttrBits, 0x40000000); oBuffer.ReadByte(m_chShadowOffsetX); oBuffer.ReadByte(m_chShadowOffsetY); oBuffer.ReadColor(m_nTextColor); oBuffer.ReadColor(m_nUnderlineColor); oBuffer.ReadColor(m_nShadeColor); oBuffer.ReadColor(m_nShadowColor); if (nSize > oBuffer.GetDistanceToLastPos()) oBuffer.ReadShort(m_shBorderFillIDRef); if (nVersion > 5030 && nSize > oBuffer.GetDistanceToLastPos()) oBuffer.ReadColor(m_nStrikeOutColor); oBuffer.RemoveLastSavedPos(); } CHWPRecordCharShape::CHWPRecordCharShape(CHWPDocInfo& oDocInfo, CXMLReader& oReader, EHanType eType) : CHWPRecord(EHWPTag::HWPTAG_HWP_CHAR_SHAPE, 0, 0), m_pParent(&oDocInfo), m_nHeight(1000), m_bItalic(false), m_bBold(false), m_eUnderline(EUnderline::NONE), m_eUnderLineShape(ELineStyle1::SOLID), m_eOutline(ELineStyle3::NONE), m_eShadow(EShadow::NONE), m_bEmboss(false), m_bEngrave(false), m_bSuperScript(false), m_bSubScript(false), m_eStrikeOutShape(ELineStyle2::NONE), m_nShadeColor(0xFFFFFFFF) { START_READ_ATTRIBUTES(oReader) { if (GetAttributeName(EAttribute::Height, eType) == sAttributeName) m_nHeight = oReader.GetInt(); else if (GetAttributeName(EAttribute::TextColor, eType)== sAttributeName) m_nTextColor = oReader.GetColor(); else if (GetAttributeName(EAttribute::ShadeColor, eType) == sAttributeName) m_nShadeColor = oReader.GetColor(0xFFFFFFFF); else if (GetAttributeName(EAttribute::UseFontSpace, eType) == sAttributeName) m_bUseFontSpace = oReader.GetBool(); else if (GetAttributeName(EAttribute::Height, eType) == sAttributeName) m_bUseKerning = oReader.GetBool(); else if (GetAttributeName(EAttribute::SymMask, eType) == sAttributeName) m_eSymMark = ((EHanType::HWPX == eType) ? GetAccent(oReader.GetTextA()) : GetAccent(oReader.GetInt())); else if (GetAttributeName(EAttribute::BorderFillId, eType) == sAttributeName) m_shBorderFillIDRef = oReader.GetInt(); } END_READ_ATTRIBUTES(oReader) WHILE_READ_NEXT_NODE_WITH_NAME(oReader) { if (GetNodeName(ENode::FontId, eType) == sNodeName) { if (nullptr == m_pParent) continue; const CHWPRecordFaceName* pFaceName = nullptr; #define UPDATE_FACENAME(elang_type)\ {\ pFaceName = dynamic_cast(m_pParent->GetFaceName(oReader.GetInt()));\ if (nullptr != pFaceName)\ m_arFontNames[(int)elang_type] = pFaceName->GetFaceName();\ } START_READ_ATTRIBUTES(oReader) { TO_LOWER(sAttributeName); if ("hangul" == sAttributeName) UPDATE_FACENAME(ELang::HANGUL) else if ("latin" == sAttributeName) UPDATE_FACENAME(ELang::LATIN) else if ("hanja" == sAttributeName) UPDATE_FACENAME(ELang::HANJA) else if ("japanese" == sAttributeName) UPDATE_FACENAME(ELang::JAPANESE) else if ("other" == sAttributeName) UPDATE_FACENAME(ELang::OTHER) else if ("symbol" == sAttributeName) UPDATE_FACENAME(ELang::SYMBOL) else if ("user" == sAttributeName) UPDATE_FACENAME(ELang::USER) } END_READ_ATTRIBUTES(oReader) } else if (GetNodeName(ENode::Ratio, eType) == sNodeName) ReadContainerData(oReader, m_arRatios, 100); else if (GetNodeName(ENode::CharSpacing, eType) == sNodeName) ReadContainerData(oReader, m_arSpacings); else if (GetNodeName(ENode::RelSize, eType) == sNodeName) ReadContainerData(oReader, m_arRelSizes, 100); else if (GetNodeName(ENode::CharOffset, eType) == sNodeName) ReadContainerData(oReader, m_arCharOffset); else if (GetNodeName(ENode::Underline, eType) == sNodeName) { START_READ_ATTRIBUTES(oReader) { if (GetAttributeName(EAttribute::Type, eType) == sAttributeName) m_eUnderline = GetUnderline(oReader.GetTextA(), eType); else if (GetAttributeName(EAttribute::Shape, eType) == sAttributeName) m_eUnderLineShape = GetLineStyle1(oReader.GetTextA(), eType); else if (GetAttributeName(EAttribute::Color, eType) == sAttributeName) m_nUnderlineColor = oReader.GetColor(); } END_READ_ATTRIBUTES(oReader) } else if (GetNodeName(ENode::Outline, eType) == sNodeName) m_eOutline = GetLineStyle3(oReader.GetAttributeA(GetAttributeName(EAttribute::Type, eType)), eType); else if (GetNodeName(ENode::Shadow, eType) == sNodeName) { START_READ_ATTRIBUTES(oReader) { if (GetAttributeName(EAttribute::Type, eType) == sAttributeName) { const std::string sType{oReader.GetTextA()}; if (GetValueName(EValue::Drop, eType)) m_eShadow = EShadow::DISCRETE; else if (GetValueName(EValue::Continuous, eType)) m_eShadow = EShadow::CONTINUOUS; else m_eShadow = EShadow::NONE; } else if (GetAttributeName(EAttribute::Color, eType) == sAttributeName) m_nShadowColor = oReader.GetColor(); else if (GetAttributeName(EAttribute::OffsetX, eType) == sAttributeName) m_chShadowOffsetX = (HWP_BYTE)oReader.GetInt(); else if (GetAttributeName(EAttribute::OffsetY, eType) == sAttributeName) m_chShadowOffsetY = (HWP_BYTE)oReader.GetInt(); } END_READ_ATTRIBUTES(oReader) } else if (GetNodeName(ENode::Italic, eType) == sNodeName) m_bItalic = true; else if (GetNodeName(ENode::Bold, eType) == sNodeName) m_bBold = true; else if (GetNodeName(ENode::Emboss, eType) == sNodeName) m_bEmboss = true; else if (GetNodeName(ENode::Engrave, eType) == sNodeName) m_bEngrave = true; else if (GetNodeName(ENode::SuperScript, eType) == sNodeName) m_bSuperScript = true; else if (GetNodeName(ENode::SubScript, eType) == sNodeName) m_bSubScript = true; else if (EHanType::HWPX == eType && "hh:strikeout" == sNodeName) { START_READ_ATTRIBUTES(oReader) { if (GetAttributeName(EAttribute::Shape, eType) == sAttributeName) m_eStrikeOutShape = GetLineStyle2(oReader.GetTextA(), eType); else if (GetAttributeName(EAttribute::Color, eType) == sAttributeName) m_nStrikeOutColor = oReader.GetColor(); } END_READ_ATTRIBUTES(oReader) } } END_WHILE } bool CHWPRecordCharShape::Bold() const { return m_bBold; } bool CHWPRecordCharShape::Italic() const { return m_bItalic; } bool CHWPRecordCharShape::Underline() const { return EUnderline::NONE != m_eUnderline; } bool CHWPRecordCharShape::StrikeOut() const { return 0x01 == m_chStrikeOut; } bool CHWPRecordCharShape::SuperScript() const { return m_bSuperScript; } bool CHWPRecordCharShape::SubScript() const { return m_bSubScript; } int CHWPRecordCharShape::GetHeight() const { return m_nHeight; } EUnderline CHWPRecordCharShape::GetUnderlineType() const { return m_eUnderline; } ELineStyle1 CHWPRecordCharShape::GetUnderlineStyle() const { return m_eUnderLineShape; } int CHWPRecordCharShape::GetUnderlineColor() const { return m_nUnderlineColor; } ELineStyle2 CHWPRecordCharShape::GetStrikeOutType() const { return m_eStrikeOutShape; } int CHWPRecordCharShape::GetStrikeOutColor() const { return m_nStrikeOutColor; } short CHWPRecordCharShape::GetRelSize(ELang eLang) const { if (ELang::MAX == eLang) return 0; return m_arRelSizes[(int)eLang]; } HWP_STRING CHWPRecordCharShape::GetFontName(ELang eLang) const { if (ELang::MAX == eLang) return HWP_STRING(); return m_arFontNames[(int)eLang]; } short CHWPRecordCharShape::GetRatio(ELang eLang) const { if (ELang::MAX == eLang) return 0; return m_arRatios[(int)eLang]; } short CHWPRecordCharShape::GetSpacing(ELang eLang) const { if (ELang::MAX == eLang) return 0; return m_arSpacings[(int)eLang]; } int CHWPRecordCharShape::GetTextColor() const { return m_nTextColor; } int CHWPRecordCharShape::GetShadeColor() const { return m_nShadeColor; } short CHWPRecordCharShape::GetBorderFillID() const { return m_shBorderFillIDRef; } }