/////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2002-2025, Open Design Alliance (the "Alliance"). // All rights reserved. // // This software and its documentation and related materials are owned by // the Alliance. The software may only be incorporated into application // programs owned by members of the Alliance, subject to a signed // Membership Agreement and Supplemental Software License Agreement with the // Alliance. The structure and organization of this software are the valuable // trade secrets of the Alliance and its suppliers. The software is also // protected by copyright law and international treaty provisions. Application // programs incorporating this software must include the following statement // with their copyright notices: // // This application incorporates Open Design Alliance software pursuant to a license // agreement with Open Design Alliance. // Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance. // All rights reserved. // // By use of this software, its documentation or related materials, you // acknowledge and accept the above terms. /////////////////////////////////////////////////////////////////////////////// #include #include "DgnImportText.h" #include "DgnImportCommon.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "DgnImportContext.h" #include "DgnImportImpl.h" #include "DgnImportTextNodeBase.h" #include "DgGiContext.h" namespace TD_DGN_IMPORT { //--------------------------------------------------------------------------------------------------- static void setTextJustification(OdDbText* dbTxt, OdDg::TextJustification tj) { switch (tj) { case OdDg::kLeftTop: case OdDg::kLeftMarginTop: dbTxt->setHorizontalMode(OdDb::kTextLeft); dbTxt->setVerticalMode(OdDb::kTextTop); break; case OdDg::kLeftCenter: case OdDg::kLeftMarginCenter: dbTxt->setHorizontalMode(OdDb::kTextLeft); dbTxt->setVerticalMode(OdDb::kTextVertMid); break; case OdDg::kLeftBottom: case OdDg::kLeftMarginBottom: dbTxt->setHorizontalMode(OdDb::kTextLeft); dbTxt->setVerticalMode(OdDb::kTextBase); break; case OdDg::kLeftDescender: dbTxt->setHorizontalMode(OdDb::kTextLeft); dbTxt->setVerticalMode(OdDb::kTextBottom); break; case OdDg::kCenterTop: dbTxt->setHorizontalMode(OdDb::kTextCenter); dbTxt->setVerticalMode(OdDb::kTextTop); break; case OdDg::kCenterCenter: dbTxt->setHorizontalMode(OdDb::kTextCenter); dbTxt->setVerticalMode(OdDb::kTextVertMid); break; case OdDg::kCenterBottom: dbTxt->setHorizontalMode(OdDb::kTextCenter); dbTxt->setVerticalMode(OdDb::kTextBase); break; case OdDg::kCenterDescender: dbTxt->setHorizontalMode(OdDb::kTextCenter); dbTxt->setVerticalMode(OdDb::kTextBottom); break; case OdDg::kRightTop: case OdDg::kRightMarginTop: dbTxt->setHorizontalMode(OdDb::kTextRight); dbTxt->setVerticalMode(OdDb::kTextTop); break; case OdDg::kRightCenter: case OdDg::kRightMarginCenter: dbTxt->setHorizontalMode(OdDb::kTextRight); dbTxt->setVerticalMode(OdDb::kTextVertMid); break; case OdDg::kRightBottom: case OdDg::kRightMarginBottom: dbTxt->setHorizontalMode(OdDb::kTextRight); dbTxt->setVerticalMode(OdDb::kTextBase); break; case OdDg::kRightDescender: dbTxt->setHorizontalMode(OdDb::kTextRight); dbTxt->setVerticalMode(OdDb::kTextBottom); break; } } //--------------------------------------------------------------------------------------------------- template bool getBold(T* txt, bool& retVal ) { return false; } //--------------------------------------------------------------------------------------------------- template<> bool getBold(OdDgText2d* txt, bool& retVal) { bool bRet = true; retVal = txt->getBoldFlag(); return bRet; } //--------------------------------------------------------------------------------------------------- template<> bool getBold(OdDgText3d* txt, bool& retVal) { bool bRet = true; retVal = txt->getBoldFlag(); return bRet; } //--------------------------------------------------------------------------------------------------- template<> bool getBold(OdDgTagElement* txt, bool& retVal) { bool bRet = true; retVal = txt->getBoldFlag(); return bRet; } //--------------------------------------------------------------------------------------------------- template bool getItalic(T* txt, bool& retVal) { return false; } //--------------------------------------------------------------------------------------------------- template<> bool getItalic(OdDgText2d* txt, bool& retVal) { bool bRet = true; retVal = txt->getSlantFlag() && OdZero(txt->getSlant()); return bRet; } //--------------------------------------------------------------------------------------------------- template<> bool getItalic(OdDgText3d* txt, bool& retVal) { bool bRet = true; retVal = txt->getSlantFlag() && OdZero(txt->getSlant()); return bRet; } //--------------------------------------------------------------------------------------------------- template<> bool getItalic( OdDgTagElement* txt, bool& retVal) { bool bRet = true; retVal = txt->getUseSlantFlag() && OdZero(txt->getSlant()); return bRet; } //--------------------------------------------------------------------------------------------------- template void setTextStyle(T* txt, OdDbText* dbTxt) { OdDgElementId dgStyleId = txt->database()->getTextStyleTable()->getAt(txt->getTextStyleEntryId()); OdDgTextStyleTableRecordPtr pDgTextStyle; bool bBold = false; bool bItalic = false; bool bBoldOverride = getBold(txt, bBold); bool bItalicOverride = getItalic(txt, bItalic); bool bEqualBold = true; bool bEqualItalics = true; bool bEqualVertical = true; OdDgFontTableRecordPtr pFontRec = OdDgFontTable::getFont(txt->database(), txt->getFontEntryId()); if( dgStyleId.isValid() ) pDgTextStyle = dgStyleId.openObject(OdDg::kForRead); bool bEqualFonts = true; if( !pDgTextStyle.isNull() ) { OdUInt32 uFontData = txt->getFontEntryId(); OdUInt32 uFontStyleData = pDgTextStyle->getFontEntryId(); bEqualFonts = uFontStyleData == uFontData; bool bStyleVertical = (pDgTextStyle->getTextDirection() & OdDg::kVertical) != 0; bool bVertical = txt->getVerticalFlag(); bEqualVertical = bStyleVertical == bVertical; } if( !pFontRec.isNull() && pFontRec->getType() == kFontTypeTrueType ) { if( bBoldOverride && !pDgTextStyle.isNull() ) bEqualBold = (bBold == pDgTextStyle->getBoldFlag()); else if( !pDgTextStyle.isNull() ) bBold = pDgTextStyle->getBoldFlag(); if( bItalicOverride && !pDgTextStyle.isNull() ) bEqualItalics = (bItalic == (pDgTextStyle->getItalicsFlag() && OdZero(pDgTextStyle->getSlant()))); else if( !pDgTextStyle.isNull() ) bItalic = pDgTextStyle->getItalicsFlag() && OdZero(pDgTextStyle->getSlant()) ; } OdDbObjectId idDbTextStyle; if (dgStyleId.isValid() && bEqualFonts && bEqualBold && bEqualItalics && bEqualVertical) idDbTextStyle = OdDgnImportContext::getObjectId(dgStyleId); if (!idDbTextStyle.isNull()) { dbTxt->setTextStyle(idDbTextStyle); } else { if( pFontRec.isNull() ) return; OdString strTTFFontName; if (pFontRec->getType() == kFontTypeRsc) strTTFFontName = odDgnImportRscFontMapping(pFontRec->getName()); if( !OdDgnImportContext::getImportFilledRscFonts() && (pFontRec->getType() == kFontTypeRsc) ) { OdDgFontTablePtr pFontTable = txt->database()->getFontTable(); OdDgFontTablePEPtr pFontPE = OdDgFontTablePEPtr(OdRxObjectPtr(pFontTable)); if( !pFontPE.isNull() && pFontPE->isFilledRscFont(pFontTable, pFontRec->getName()) ) { pFontRec = pFontTable->getFont(txt->database()->appServices()->getAlternateFontName()); if (pFontRec.isNull()) pFontRec = pFontTable->getFont(txt->database()->appServices()->getFAST_FONT()); } } OdString styleName = L"Style-" + pFontRec->getName(); if( txt->getVerticalFlag() ) { styleName = L"Style-V-" + pFontRec->getName(); } if( (pFontRec->getType() == kFontTypeTrueType) && (bBold || bItalic ) ) { styleName += L"-"; if( bBold ) styleName += L"B"; if( bItalic ) styleName += L"I"; } OdDbTextStyleTablePtr tst = dbTxt->database()->getTextStyleTableId().safeOpenObject(OdDb::kForWrite); OdDbObjectId styleId = tst->getAt(styleName); bool bCreateStyle = true; if( styleId.isValid() ) { OdGiTextStyle giStyle = giTextStyleFromDb(styleId); giStyle.loadStyleRec(dbTxt->database()); if ((giStyle.isShxFont() && (pFontRec->getType() == kFontTypeTrueType)) || (!giStyle.isShxFont() && (pFontRec->getType() != kFontTypeTrueType))) { if( pFontRec->getType() == kFontTypeTrueType ) styleName += L"_TTF"; else styleName += L"_SHX"; styleId = tst->getAt(styleName); } } if( styleId.isValid() ) { OdDgnImportContext::setResourceUsage(styleId); dbTxt->setTextStyle(styleId); bCreateStyle = false; } if( bCreateStyle ) { OdDbTextStyleTableRecordPtr ts = OdDbTextStyleTableRecord::createObject(); ts->setName(styleName); OdDbObjectId idStyle = tst->add(ts); if (!strTTFFontName.isEmpty()) { ts->setFont(strTTFFontName, bBold, bItalic, 0, 0); } else if (pFontRec->getType() == kFontTypeShx) { ts->setFileName(pFontRec->getName()); } else if( pFontRec->getType() == kFontTypeRsc && OdDgnImportContext::getDgnImporter() ) { OdDgnImportContext::getDgnImporter()->createShxFontFromRscFont( pFontRec->getName() ); ts->setFileName(pFontRec->getName() + L".shx"); } else if (pFontRec->getType() == kFontTypeTrueType) { ts->setFont(pFontRec->getName(), bBold, bItalic, 0, 0); } else return; ts->setIsVertical( txt->getVerticalFlag() ); dbTxt->setTextStyle(idStyle); } } } //--------------------------------------------------------------------------------------------------- template static bool isUnderlineText(T* txt ) { bool bRet = txt->getUnderlineFlag(); return bRet; } //--------------------------------------------------------------------------------------------------- template static bool isOverlineText(T* txt ) { bool bRet = txt->getOverlineFlag(); return bRet; } //--------------------------------------------------------------------------------------------------- void convertText2dToMText( OdDgText2d* txt, OdDbBlockTableRecord* owner ) { double dTextSize = fabs(txt->getHeightMultiplier()); double dSymbolWidth = fabs(txt->getLengthMultiplier()); if( OdZero(dTextSize) ) return; OdDbDatabase* pDb = owner->database(); OdDgTextNodeImportData curData; OdGePoint2d ptOrigin = txt->getPosition(); OdGePoint3d ptPosition( ptOrigin.x, ptOrigin.y, 0.0); OdGeVector3d vrNormal = OdGeVector3d::kZAxis; double dRotAngle = txt->getRotation(); OdDbObjectId idTextStyle = getDbTextStyle(txt, dTextSize, pDb, curData, false); OdDbMTextPtr pMText = OdDbMText::createObject(); pMText->setDatabaseDefaults(pDb); pMText->setNormal(vrNormal); pMText->setAttachment( convertTextNodeJustification(txt->getJustification())); pMText->setLocation(ptPosition); pMText->setRotation(dRotAngle); pMText->setTextHeight(dTextSize); pMText->setTextStyle(idTextStyle); OdUInt32 uMaxLength = txt->getText().getLength(); if( !OdZero(dSymbolWidth) ) pMText->setWidth(uMaxLength * dSymbolWidth); else pMText->setWidth(uMaxLength * dTextSize); pMText->setLineSpacingStyle(OdDb::kAtLeast); pMText->setLineSpacingFactor(1.0); copyEntityProperties(txt, pMText); OdCmColor curColor = pMText->color(); if (curColor.colorMethod() == OdCmEntityColor::kByColor) { curData.m_bUseRGBColor = true; curData.m_uRGBColor = curColor.color(); } else if ((curColor.colorMethod() == OdCmEntityColor::kByACI) || (curColor.colorMethod() == OdCmEntityColor::kByDgnIndex)) { curData.m_bUseRGBColor = false; curData.m_uColorIndex = curColor.colorIndex(); } else if (curColor.colorMethod() == OdCmEntityColor::kByLayer) { curData.m_bUseRGBColor = false; curData.m_uColorIndex = OdCmEntityColor::kACIbyLayer; } else { curData.m_bUseRGBColor = false; curData.m_uColorIndex = OdCmEntityColor::kACIbyBlock; } OdString strMTextContents = addTextItem(txt, curData); pMText->setContents(strMTextContents); owner->appendOdDbEntity(pMText); if (pMText->actualWidth() < pMText->width() * 0.9) { pMText->setWidth(pMText->actualWidth()*1.1); } } //--------------------------------------------------------------------------------------------------- void OdDgText2dImportPE::subImportElement(OdDgElement* e, OdDbBlockTableRecord* owner) { OdDgText2d* txt = (OdDgText2d*)e; if( OdZero(txt->getHeightMultiplier()) ) return; if( OdDgnImportContext::isImportDgTextAsDbMText() ) { convertText2dToMText(txt, owner); return; } OdDbTextPtr dbTxt = OdDbText::createObject(); dbTxt->setDatabaseDefaults(owner->database()); owner->database()->addOdDbObject(dbTxt, owner->objectId()); OdDgElementId idDgOwner = txt->ownerId(); if( !idDgOwner.isNull() ) { OdDgElementPtr pDgOwner = idDgOwner.openObject(OdDg::kForRead); if( !pDgOwner.isNull() && (pDgOwner->isA() == OdDgTextNode2d::desc()) ) { OdDgTextNode2dPtr pDgTextNode = pDgOwner; if( !pDgTextNode.isNull() && !dbTxt.isNull() ) { OdDgElementId idOwnerLevel = OdDgnImportContext::getLevelOverride(pDgTextNode->getLevelId()); OdDgnImportContext::setLockLevelId(true, idOwnerLevel); } } } copyEntityProperties(txt, dbTxt); OdDgnImportContext::setLockLevelId(false, OdDgElementId()); owner->appendOdDbEntity(dbTxt); setTextStyle(txt, dbTxt); OdString strText = txt->getText(); if( !OdDgnImportContext::getConvertEmptyDataFieldsToSpacesFlag() && !OdDgnImportContext::getUnderlineDataFieldsFlag() ) { if( txt->getTextEditFieldCount() > 0 ) { for( OdInt16 i = 0; i < txt->getTextEditFieldCount(); i++ ) { OdDgTextEditField txtField = txt->getTextEditFieldAt(i); strText = convertEmptyDataFieldsTo_( strText, txtField ); } } } if( isUnderlineText(txt) ) { strText = L"%%u" + strText; } else if (OdDgnImportContext::getUnderlineDataFieldsFlag() && (txt->getTextEditFieldCount() > 0)) { OdString strResultText; OdUInt32 uStart = 0; for (OdInt16 i = 0; i < txt->getTextEditFieldCount(); i++) { OdDgTextEditField txtField = txt->getTextEditFieldAt(i); if (txtField.m_uLength == 0) continue; if (uStart < (OdUInt32)(txtField.m_uStartPosition - 1)) strResultText += strText.mid(uStart, txtField.m_uStartPosition - 1 - uStart); strResultText += L"%%U" + strText.mid(txtField.m_uStartPosition - 1, txtField.m_uLength); uStart = txtField.m_uStartPosition + txtField.m_uLength - 1; if (uStart < (OdUInt32)(strText.getLength())) strResultText += L"%%u"; } if (uStart < (OdUInt32)strText.getLength()) strResultText += strText.right(strText.getLength() - uStart); strText = strResultText; } if( isOverlineText(txt) ) { strText = L"%%o" + strText; } OdDgFontTableRecordPtr pFontRec = txt->database()->getFontTable(OdDg::kForRead)->getFont(txt->getFontEntryId()); if (pFontRec.isNull() || pFontRec->getType() == kFontTypeRsc) // default Char_Fast_Font font if rsc too strText = convertTextSymbolsFromRscToShx(txt->database(), strText, pFontRec); dbTxt->setTextString(strText); if( txt->getSubscriptFlag() ) dbTxt->setHeight(fabs(txt->getHeightMultiplier()*0.3)); else if( txt->getSuperscriptFlag() ) dbTxt->setHeight(fabs(txt->getHeightMultiplier()*0.3)); else dbTxt->setHeight(fabs(txt->getHeightMultiplier())); if( txt->getHeightMultiplier() < 0 ) dbTxt->mirrorInY(true); if( txt->getLengthMultiplier() < 0 ) dbTxt->mirrorInX(true); setTextJustification(dbTxt, txt->getJustification()); dbTxt->setRotation(txt->getRotation()); OdGePoint2d p2(txt->getPosition()); OdGePoint3d p(p2.x, p2.y, 0); { //There are dgn files with invalid oblique angle double oblique = txt->getSlant(); oblique -= floor(oblique / Oda2PI)*Oda2PI; if (oblique >= OdaPI) oblique -= Oda2PI; if (fabs(oblique) <= OdaToRadian(85.)) dbTxt->setOblique(oblique); } if (!OdZero(txt->getHeightMultiplier()) && !OdZero(txt->getLengthMultiplier())) dbTxt->setWidthFactor(fabs(txt->getLengthMultiplier())/fabs(txt->getHeightMultiplier())); if (dbTxt->verticalMode() == OdDb::kTextBase && dbTxt->horizontalMode() == OdDb::kTextLeft) dbTxt->setPosition(p); else dbTxt->setAlignmentPoint(p); dbTxt->adjustAlignment(owner->database()); double dScriptYOffset = 0; if (txt->getSuperscriptFlag()) { switch (dbTxt->verticalMode()) { case OdDb::kTextVertMid: dScriptYOffset = fabs(txt->getHeightMultiplier())*0.35; break; case OdDb::kTextBase: case OdDb::kTextBottom: dScriptYOffset = fabs(txt->getHeightMultiplier())*0.7; break; } } else if (txt->getSubscriptFlag()) { switch (dbTxt->verticalMode()) { case OdDb::kTextTop: dScriptYOffset = -fabs(txt->getHeightMultiplier())*0.9; break; case OdDb::kTextVertMid: dScriptYOffset = -fabs(txt->getHeightMultiplier())*0.5; break; case OdDb::kTextBase: case OdDb::kTextBottom: dScriptYOffset = -fabs(txt->getHeightMultiplier())*0.2; break; } } if (!OdZero(dScriptYOffset)) { double dRotation = txt->getRotation(); OdGeVector3d vrTextDirY = OdGeVector3d::kYAxis; vrTextDirY.rotateBy(dRotation, OdGeVector3d::kZAxis); dbTxt->transformBy(OdGeMatrix3d::translation(vrTextDirY * dScriptYOffset)); } if( txt->getOffsetFlag() ) { OdGeVector3d vrOffset( txt->getLineOffset().x, txt->getLineOffset().y, 0 ); vrOffset.rotateBy( txt->getRotation(), OdGeVector3d::kZAxis ); OdGeMatrix3d matTransform = OdGeMatrix3d::translation( vrOffset ); dbTxt->transformBy(matTransform); } OdDgnImportPathToDwgObject dwgPath; dwgPath.m_idPath.objectIds().push_back( dbTxt->objectId() ); dwgPath.m_bExists = true; OdDgnImportContext::addObjectPath( e->elementId(), dwgPath ); } //--------------------------------------------------------------------------------------------------- void convertText3dToMText(OdDgText3d* txt, OdDbBlockTableRecord* owner) { double dTextSize = fabs(txt->getHeightMultiplier()); double dSymbolWidth = fabs(txt->getLengthMultiplier()); if (OdZero(dTextSize)) return; OdDbDatabase* pDb = owner->database(); OdDgTextNodeImportData curData; OdGePoint3d ptPosition = txt->getPosition(); OdGeMatrix3d matTransform = txt->getRotation().getMatrix(); matTransform.transposeIt(); OdGeVector3d vrNormal = OdGeVector3d::kZAxis; vrNormal = vrNormal.transformBy(matTransform); if (!OdZero(vrNormal.length())) vrNormal.normalize(); else vrNormal = OdGeVector3d::kZAxis; OdGeVector3d vrZAxis = OdGeVector3d::kZAxis; OdGeVector3d vrXAxis = OdGeVector3d::kXAxis; vrZAxis = vrZAxis.transformBy(matTransform); vrXAxis = vrXAxis.transformBy(matTransform); if( !OdZero(vrZAxis.length()) ) vrZAxis.normalize(); else vrZAxis = OdGeVector3d::kZAxis; if (!OdZero(vrXAxis.length())) vrXAxis.normalize(); else vrXAxis = OdGeVector3d::kXAxis; double dRotAngle = OdGeMatrix3d::planeToWorld(vrZAxis).getCsXAxis().angleTo(vrXAxis, vrZAxis); OdDbObjectId idTextStyle = getDbTextStyle(txt, dTextSize, pDb, curData, false); OdDbMTextPtr pMText = OdDbMText::createObject(); pMText->setDatabaseDefaults(pDb); pMText->setNormal(vrNormal); pMText->setAttachment(convertTextNodeJustification(txt->getJustification())); pMText->setLocation(ptPosition); pMText->setRotation(dRotAngle); pMText->setTextHeight(dTextSize); pMText->setTextStyle(idTextStyle); OdUInt32 uMaxLength = txt->getText().getLength(); if (!OdZero(dSymbolWidth)) pMText->setWidth(uMaxLength * dSymbolWidth); else pMText->setWidth(uMaxLength * dTextSize); pMText->setLineSpacingStyle(OdDb::kAtLeast); pMText->setLineSpacingFactor(1.0); copyEntityProperties(txt, pMText); OdCmColor curColor = pMText->color(); if (curColor.colorMethod() == OdCmEntityColor::kByColor) { curData.m_bUseRGBColor = true; curData.m_uRGBColor = curColor.color(); } else if ((curColor.colorMethod() == OdCmEntityColor::kByACI) || (curColor.colorMethod() == OdCmEntityColor::kByDgnIndex)) { curData.m_bUseRGBColor = false; curData.m_uColorIndex = curColor.colorIndex(); } else if (curColor.colorMethod() == OdCmEntityColor::kByLayer) { curData.m_bUseRGBColor = false; curData.m_uColorIndex = OdCmEntityColor::kACIbyLayer; } else { curData.m_bUseRGBColor = false; curData.m_uColorIndex = OdCmEntityColor::kACIbyBlock; } OdString strMTextContents = addTextItem(txt, curData); pMText->setContents(strMTextContents); owner->appendOdDbEntity(pMText); if (pMText->actualWidth() < pMText->width() * 0.9) { pMText->setWidth(pMText->actualWidth()*1.1); } } //--------------------------------------------------------------------------------------------------- void OdDgText3dImportPE::subImportElement(OdDgElement* e, OdDbBlockTableRecord* owner) { OdDgText3d* txt = (OdDgText3d*)e; if( OdZero(txt->getHeightMultiplier()) ) return; if (OdDgnImportContext::isImportDgTextAsDbMText()) { convertText3dToMText(txt, owner); return; } OdDbTextPtr dbTxt = OdDbText::createObject(); dbTxt->setDatabaseDefaults(owner->database()); owner->database()->addOdDbObject(dbTxt, owner->objectId()); OdDgElementId idDgOwner = txt->ownerId(); if (!idDgOwner.isNull()) { OdDgElementPtr pDgOwner = idDgOwner.openObject(OdDg::kForRead); if (!pDgOwner.isNull() && (pDgOwner->isA() == OdDgTextNode2d::desc())) { OdDgTextNode2dPtr pDgTextNode = pDgOwner; if (!pDgTextNode.isNull() && !dbTxt.isNull()) { OdDgElementId idOwnerLevel = OdDgnImportContext::getLevelOverride(pDgTextNode->getLevelId()); OdDgnImportContext::setLockLevelId(true, idOwnerLevel); } } } copyEntityProperties(txt, dbTxt); OdDgnImportContext::setLockLevelId(false, OdDgElementId()); owner->appendOdDbEntity(dbTxt); setTextStyle(txt, dbTxt); OdString strText = txt->getText(); if( !OdDgnImportContext::getConvertEmptyDataFieldsToSpacesFlag() && !OdDgnImportContext::getUnderlineDataFieldsFlag() ) { if( txt->getTextEditFieldCount() > 0 ) { for( OdInt16 i = 0; i < txt->getTextEditFieldCount(); i++ ) { OdDgTextEditField txtField = txt->getTextEditFieldAt(i); strText = convertEmptyDataFieldsTo_( strText, txtField ); } } } if( isUnderlineText(txt) ) { strText = L"%%U" + strText; } else if (OdDgnImportContext::getUnderlineDataFieldsFlag() && (txt->getTextEditFieldCount() > 0)) { OdString strResultText; OdUInt32 uStart = 0; for (OdInt16 i = 0; i < txt->getTextEditFieldCount(); i++) { OdDgTextEditField txtField = txt->getTextEditFieldAt(i); if (txtField.m_uLength == 0) continue; if (uStart < (OdUInt32)(txtField.m_uStartPosition - 1)) strResultText += strText.mid(uStart, txtField.m_uStartPosition - 1 - uStart); strResultText += L"%%U" + strText.mid(txtField.m_uStartPosition - 1, txtField.m_uLength); uStart = txtField.m_uStartPosition + txtField.m_uLength - 1; if (uStart < (OdUInt32)(strText.getLength())) strResultText += L"%%u"; } if (uStart < (OdUInt32)strText.getLength()) strResultText += strText.right(strText.getLength() - uStart); strText = strResultText; } if( isOverlineText(txt) ) { strText = L"%%O" + strText; } OdDgFontTableRecordPtr pFontRec = txt->database()->getFontTable(OdDg::kForRead)->getFont(txt->getFontEntryId()); if( pFontRec.isNull() || pFontRec->getType() == kFontTypeRsc ) // default Char_Fast_Font font if rsc too strText = convertTextSymbolsFromRscToShx(e->database(), strText, pFontRec); dbTxt->setTextString(strText); if (txt->getSubscriptFlag()) dbTxt->setHeight(fabs(txt->getHeightMultiplier()*0.3)); else if (txt->getSuperscriptFlag()) dbTxt->setHeight(fabs(txt->getHeightMultiplier()*0.3)); else dbTxt->setHeight(fabs(txt->getHeightMultiplier())); if( txt->getHeightMultiplier() < 0 ) dbTxt->mirrorInY(true); if( txt->getLengthMultiplier() < 0 ) dbTxt->mirrorInX(true); dbTxt->transformBy(txt->getRotation().getMatrix().transpose()); setTextJustification(dbTxt, txt->getJustification()); { //There are dgn files with invalid oblique angle double oblique = txt->getSlant(); oblique -= floor(oblique/Oda2PI)*Oda2PI; if (oblique >= OdaPI) oblique -= Oda2PI; if (fabs(oblique) <= OdaToRadian(85.)) dbTxt->setOblique(oblique); } if (!OdZero(txt->getHeightMultiplier()) && !OdZero(txt->getLengthMultiplier())) dbTxt->setWidthFactor(fabs(txt->getLengthMultiplier())/fabs(txt->getHeightMultiplier())); if (dbTxt->verticalMode() == OdDb::kTextBase && dbTxt->horizontalMode() == OdDb::kTextLeft) dbTxt->setPosition(txt->getPosition()); else dbTxt->setAlignmentPoint(txt->getPosition()); dbTxt->adjustAlignment(owner->database()); double dScriptYOffset = 0; if (txt->getSuperscriptFlag()) { switch (dbTxt->verticalMode()) { case OdDb::kTextVertMid: dScriptYOffset = fabs(txt->getHeightMultiplier())*0.35; break; case OdDb::kTextBase: case OdDb::kTextBottom: dScriptYOffset = fabs(txt->getHeightMultiplier())*0.7; break; } } else if (txt->getSubscriptFlag()) { switch (dbTxt->verticalMode()) { case OdDb::kTextTop: dScriptYOffset = -fabs(txt->getHeightMultiplier())*0.9; break; case OdDb::kTextVertMid: dScriptYOffset = -fabs(txt->getHeightMultiplier())*0.5; break; case OdDb::kTextBase: case OdDb::kTextBottom: dScriptYOffset = -fabs(txt->getHeightMultiplier())*0.2; break; } } if( !OdZero(dScriptYOffset) ) { OdGeQuaternion quatRot = txt->getRotation(); OdGeVector3d vrTextDirY = OdGeVector3d::kYAxis; quatRot.rotateOpposite(vrTextDirY); dbTxt->transformBy(OdGeMatrix3d::translation(vrTextDirY * dScriptYOffset)); } if( txt->getOffsetFlag() ) { OdGeVector3d vrOffset( txt->getLineOffset().x, txt->getLineOffset().y, 0 ); vrOffset.transformBy( txt->getRotation().getMatrix().transpose() ); OdGeMatrix3d matTransform = OdGeMatrix3d::translation( vrOffset ); dbTxt->transformBy(matTransform); } OdDgnImportPathToDwgObject dwgPath; dwgPath.m_idPath.objectIds().push_back( dbTxt->objectId() ); dwgPath.m_bExists = true; OdDgnImportContext::addObjectPath( e->elementId(), dwgPath ); } //--------------------------------------------------------------------------------------------------- OdString getTagValue(OdDgTagElement* tag) { OdString strRet; switch( tag->getDataType() ) { case OdDgTagDefinition::kChar: strRet = tag->getString(); break; case OdDgTagDefinition::kInt16: strRet.format(L"%d", tag->getInt16()); break; case OdDgTagDefinition::kInt32: strRet.format(L"%d", tag->getInt32()); break; case OdDgTagDefinition::kDouble: strRet.format(L"%f", tag->getDouble()); break; } return strRet; } //--------------------------------------------------------------------------------------------------- bool isTagAssociatedWithCellHeader(OdDgElementId& idDgTagAssociatedId, OdDgTagElement* tag, OdDbBlockTableRecordPtr& pCellBlock, OdDbObjectId& idTagOwner) { if( idTagOwner.isNull() || idDgTagAssociatedId.isNull() ) return false; OdDgElementPtr pElement = idDgTagAssociatedId.openObject(OdDg::kForRead); if( pElement.isNull() || !isCellHeaderElement(pElement) ) return false; OdDbObjectPtr pBlockRefObj = idTagOwner.openObject(OdDb::kForRead); if (pBlockRefObj.isNull() || !pBlockRefObj->isKindOf(OdDbBlockReference::desc())) return false; OdDbBlockReferencePtr pBlockRef = pBlockRefObj; OdDbObjectId idBlockDef = pBlockRef->blockTableRecord(); if (idBlockDef.isNull()) return false; pCellBlock = idBlockDef.openObject(OdDb::kForWrite); return true; } //--------------------------------------------------------------------------------------------------- bool isTagIntoSharedCell( OdDgElementId& idSharedCellRef, OdDgTagElement* tag) { bool bRet = false; if(idSharedCellRef.isNull() ) return bRet; OdDgElementPtr pElm = idSharedCellRef.openObject(OdDg::kForRead); if (pElm.isNull() || !pElm->isKindOf(OdDgSharedCellReference::desc())) return bRet; OdDgSharedCellReferencePtr pSharedCellRef = pElm; OdDgSharedCellDefinitionPtr pSharedCellDef = pSharedCellRef->findDefinition(); if( pSharedCellDef.isNull() ) return bRet; OdDgElementId idBaseTagSet; OdUInt16 uBaseTagDef; tag->getTagDefinitionId(idBaseTagSet, uBaseTagDef); OdDgElementIteratorPtr pIter = pSharedCellDef->createIterator(); for(; !pIter->done(); pIter->step()) { OdDgElementPtr pItem = pIter->item().openObject(OdDg::kForRead); if( pItem->isKindOf(OdDgTagElement::desc()) ) { OdDgTagElementPtr pTag = pItem; OdDgElementId idCurTagSet; OdUInt16 uCurTagDef; pTag->getTagDefinitionId(idCurTagSet, uCurTagDef); if ((idCurTagSet == idBaseTagSet) && (uCurTagDef == uBaseTagDef)) { bRet = true; break; } } } return bRet; } //--------------------------------------------------------------------------------------------------- bool createAttributeDefinition(OdDgTagElement* tag, const OdDgTagDefinitionPtr& pDgTagDef, OdDbBlockTableRecord* owner) { if (pDgTagDef.isNull() || OdZero(tag->getHeightMultiplier()) ) return false; OdDbAttributeDefinitionPtr pDbAttrDef = OdDbAttributeDefinition::createObject(); pDbAttrDef->setDatabaseDefaults(owner->database()); owner->database()->addOdDbObject(pDbAttrDef, owner->objectId()); copyEntityProperties(tag, pDbAttrDef); owner->appendOdDbEntity(pDbAttrDef); setTextStyle(tag, pDbAttrDef); pDbAttrDef->setTag(pDgTagDef->getName()); pDbAttrDef->setPrompt(pDgTagDef->getPrompt()); pDbAttrDef->setInvisible(!pDgTagDef->getDisplayTagFlag()); pDbAttrDef->setConstant(false); pDbAttrDef->setVerifiable(pDgTagDef->getConfirmFlag()); OdString strTagValue = getTagValue(tag); OdDgFontTableRecordPtr pFontRec = tag->database()->getFontTable(OdDg::kForRead)->getFont(tag->getFontEntryId()); if (pFontRec.isNull() || pFontRec->getType() == kFontTypeRsc) // default Char_Fast_Font font if rsc too strTagValue = convertTextSymbolsFromRscToShx(tag->database(), strTagValue, pFontRec); pDbAttrDef->setTextString(strTagValue); pDbAttrDef->setHeight(fabs(tag->getHeightMultiplier())); if (tag->getHeightMultiplier() < 0) pDbAttrDef->mirrorInY(true); if (tag->getLengthMultiplier() < 0) pDbAttrDef->mirrorInX(true); OdGeMatrix3d matTransform; if (tag->get3dFormatFlag()) { matTransform = tag->getRotation3d().getMatrix(); matTransform.transposeIt(); } else { matTransform = OdGeMatrix3d::rotation(tag->getRotation2d(), OdGeVector3d::kZAxis); } pDbAttrDef->transformBy(matTransform); setTextJustification(pDbAttrDef, tag->getJustification()); { //There are dgn files with invalid oblique angle double oblique = tag->getSlant(); oblique -= floor(oblique / Oda2PI)*Oda2PI; if (oblique >= OdaPI) oblique -= Oda2PI; if (fabs(oblique) <= OdaToRadian(85.)) pDbAttrDef->setOblique(oblique); } if (!OdZero(tag->getHeightMultiplier()) && !OdZero(tag->getLengthMultiplier())) pDbAttrDef->setWidthFactor(fabs(tag->getLengthMultiplier()) / fabs(tag->getHeightMultiplier())); if (pDbAttrDef->verticalMode() == OdDb::kTextBase && pDbAttrDef->horizontalMode() == OdDb::kTextLeft) pDbAttrDef->setPosition(tag->getOrigin()); else pDbAttrDef->setAlignmentPoint(tag->getOrigin()); if (tag->getOffsetUsedFlag()) { matTransform = OdGeMatrix3d::translation(tag->getOffset()); pDbAttrDef->transformBy(matTransform); } pDbAttrDef->adjustAlignment(owner->database()); return true; } //--------------------------------------------------------------------------------------------------- void correctDwgAttributePositionByDgnTagPosition(OdDbEntity* pDbAttr, OdDgTagElement* pTag) { if (!pTag || !pDbAttr) return; OdString strTagData = pTag->getString(); OdDgDatabase* pDb = pTag->database(); //OdDg::TextJustification uJust = pTag->getJustification(); //if ((uJust == OdDg::kLeftTop) || // (uJust == OdDg::kLeftCenter) || // (uJust == OdDg::kLeftBottom) || // (uJust == OdDg::kLeftMarginTop) || // (uJust == OdDg::kLeftMarginCenter) || // (uJust == OdDg::kLeftMarginBottom) || // (uJust == OdDg::kLeftDescender) || // strTagData.isEmpty() || !pDb // ) { if (pDbAttr->isKindOf(OdDbAttribute::desc())) { OdDbAttributePtr pAttr = pDbAttr; if (pAttr->verticalMode() == OdDb::kTextBase && pAttr->horizontalMode() == OdDb::kTextLeft) pAttr->setPosition(pTag->getOrigin()); else pAttr->setAlignmentPoint(pTag->getOrigin()); } else { OdDbTextPtr pText = pDbAttr; if (pText->verticalMode() == OdDb::kTextBase && pText->horizontalMode() == OdDb::kTextLeft) pText->setPosition(pText->position()); else pText->setAlignmentPoint(pText->alignmentPoint()); } return; } /* OdDgTextStyleTableRecordPtr pRecord; OdInt32 entryIdForTextStyle = pTag->getTextStyleEntryId(); bool bStyleIsNone(true); if (entryIdForTextStyle > 0) { OdDgTextStyleTablePtr pTable = pDb->getTextStyleTable(); OdDgElementId idTextStyle = pTable->getAt(entryIdForTextStyle); if (!idTextStyle.isNull()) { pRecord = idTextStyle.openObject(); bStyleIsNone = false; } } else pRecord = pDb->getTextStyleTable()->getDefaultData(); if (pRecord.isNull()) pRecord = pDb->getTextStyleTable()->getDefaultData(); OdGiTextStyle style; pRecord->getGiTextStyle(style); bool bTTFFont = false; style.setBackward(false); style.setUpsideDown(false); OdDgFontTableRecordPtr pFont = OdDgFontTable::getFont(pDb, pTag->getFontEntryId()); if (pFont.isNull()) return; bool bBold = pTag->getBoldFlag(); bool bItalic = !OdZero(pTag->getSlant()); bool bVertical = pTag->getVerticalFlag(); if (pFont->getType() == kFontTypeTrueType) { style.setFont(pFont.get()->getName(), bBold, bItalic, 0, 0); bTTFFont = true; //bVertical = false; } else { OdString strBigFontName = style.bigFontFileName(); style.setFont(pFont.get()->getName(), false, false, 0, 0); style.setFileName(pFont.get()->getName()); if (!strBigFontName.isEmpty() && (pFont->getType() == kFontTypeShx)) { style.setBigFontFileName(strBigFontName); } } style.loadStyleRec(pDb); style.setCodePage(OdCharMapper::ansiCpToAcadCp(pTag->getCodepage())); style.setTextSize(pTag->getHeightMultiplier()); style.setXScale(fabs(pTag->getLengthMultiplier()) / fabs(pTag->getHeightMultiplier())); double dIntercharSpacing = pTag->getCharacterSpacing(); if ((pTag->getLengthMultiplier() < 0) && !pTag->getAcadInterCharSpacingFlag()) { dIntercharSpacing *= -1; } if (pTag->getAcadInterCharSpacingFlag()) { style.setIsUseIntercharSpacing(false); style.setIsFixedIntercharSpacing(false); style.setTrackingPercent(dIntercharSpacing); } else if (pTag->getFixedWidthSpacingFlag()) { style.setIsUseIntercharSpacing(true); style.setIsFixedIntercharSpacing(true); if (style.isVertical() || OdZero(pTag->getLengthMultiplier())) style.setIntercharSpacing(dIntercharSpacing / fabs(pTag->getHeightMultiplier())); else style.setIntercharSpacing(dIntercharSpacing / fabs(pTag->getLengthMultiplier())); } else { style.setIsUseIntercharSpacing(true); style.setIsFixedIntercharSpacing(false); if (style.isVertical() || OdZero(pTag->getLengthMultiplier())) style.setIntercharSpacing(dIntercharSpacing / fabs(pTag->getHeightMultiplier())); else style.setIntercharSpacing(dIntercharSpacing / fabs(pTag->getLengthMultiplier())); } style.setVertical(bVertical); if (!bVertical) style.setObliquingAngle(pTag->getSlant()); else style.setObliquingAngle(0); OdGeQuaternion rotation; if (pTag->get3dFormatFlag()) rotation = pTag->getRotation3d(); else { OdGeMatrix3d matRotation = OdGeMatrix3d::rotation(pTag->getRotation2d(), OdGeVector3d::kZAxis); matRotation = matRotation.transposeIt(); rotation.set(matRotation); } OdGeVector3d xAxis = OdGeVector3d::kXAxis, zAxis = OdGeVector3d::kZAxis, yAxis = OdGeVector3d::kYAxis; OdGeVector3d direction = rotation.rotateOpposite(xAxis); OdGeVector3d directionY = rotation.rotateOpposite(yAxis); OdGeVector3d normal = rotation.rotateOpposite(zAxis); if (pTag->getLengthMultiplier() < 0) { style.setBackward(true); } if (pTag->getHeightMultiplier() < 0) { style.setUpsideDown(true); direction = -direction; } OdGeVector3d vrTextXDir = direction; if ((style.isBackward() && !style.isUpsideDown()) || (!style.isBackward() && style.isUpsideDown())) { vrTextXDir = -vrTextXDir; if (!OdZero(pTag->getSlant())) { style.setObliquingAngle(-pTag->getSlant()); } } OdStaticRxObject giContext; giContext.setDatabase(pDb, false); OdGePoint3d ptMin, ptMax, ptEndPos; giContext.textExtentsBox(style, strTagData, strTagData.getLength(), 0, ptMin, ptMax, &ptEndPos); double dTextLength = ptEndPos.x; double dTextFullLength = ptMax.x; double dOffset = dTextFullLength - dTextLength; switch (uJust) { case OdDg::kCenterTop: case OdDg::kCenterCenter: case OdDg::kCenterBottom: case OdDg::kCenterDescender: { if( pDbAttr->isKindOf(OdDbAttribute::desc()) ) { OdDbAttributePtr pAttr = pDbAttr; if (pAttr->verticalMode() == OdDb::kTextBase && pAttr->horizontalMode() == OdDb::kTextLeft) pAttr->setPosition(pTag->getOrigin() - direction * dOffset/2.0); else pAttr->setAlignmentPoint(pTag->getOrigin() - direction * dOffset/2.0); } else { OdDbTextPtr pText = pDbAttr; if (pText->verticalMode() == OdDb::kTextBase && pText->horizontalMode() == OdDb::kTextLeft) pText->setPosition(pText->position() - direction * dOffset / 2.0); else pText->setAlignmentPoint(pText->alignmentPoint() - direction * dOffset / 2.0); } } break; case OdDg::kRightMarginTop: case OdDg::kRightMarginCenter: case OdDg::kRightMarginBottom: case OdDg::kRightTop: case OdDg::kRightCenter: case OdDg::kRightBottom: case OdDg::kRightDescender: { if (pDbAttr->isKindOf(OdDbAttribute::desc())) { OdDbAttributePtr pAttr = pDbAttr; if (pAttr->verticalMode() == OdDb::kTextBase && pAttr->horizontalMode() == OdDb::kTextLeft) pAttr->setPosition(pTag->getOrigin() - direction * dOffset ); else pAttr->setAlignmentPoint(pTag->getOrigin() - direction * dOffset); } else { OdDbTextPtr pText = pDbAttr; if (pText->verticalMode() == OdDb::kTextBase && pText->horizontalMode() == OdDb::kTextLeft) pText->setPosition(pText->position() - direction * dOffset); else pText->setAlignmentPoint(pText->alignmentPoint() - direction * dOffset); } } break; } */ } //--------------------------------------------------------------------------------------------------- void createAttribute(OdDgTagElement* tag, const OdDgTagDefinitionPtr& pDgTagDef, OdDbBlockReferencePtr& ownerBlockRef, OdDbBlockTableRecord* owner) { if( pDgTagDef.isNull() ) return; OdDbAttributePtr dbAttr = OdDbAttribute::createObject(); dbAttr->setDatabaseDefaults(owner->database()); owner->database()->addOdDbObject(dbAttr, ownerBlockRef->objectId()); copyEntityProperties(tag, dbAttr); ownerBlockRef->appendAttribute(dbAttr); setTextStyle(tag, dbAttr); if (!pDgTagDef.isNull()) dbAttr->setTag(pDgTagDef->getName()); dbAttr->setTextString(getTagValue(tag)); dbAttr->setHeight(fabs(tag->getHeightMultiplier())); dbAttr->setInvisible(tag->getInvisibleFlag()); if( tag->getFreezeGroup() != 0 ) dbAttr->setInvisible(true); if (tag->getHeightMultiplier() < 0) dbAttr->mirrorInY(true); if (tag->getLengthMultiplier() < 0) dbAttr->mirrorInX(true); OdGeMatrix3d matTransform; if (tag->get3dFormatFlag()) { matTransform = tag->getRotation3d().getMatrix(); matTransform.transposeIt(); } else { matTransform = OdGeMatrix3d::rotation(tag->getRotation2d(), OdGeVector3d::kZAxis); } dbAttr->transformBy(matTransform); setTextJustification(dbAttr, tag->getJustification()); try { //There are dgn files with invalid oblique angle double oblique = tag->getSlant(); oblique -= floor(oblique / Oda2PI)*Oda2PI; if (oblique >= OdaPI) oblique -= Oda2PI; if (fabs(oblique) <= OdaToRadian(85.)) dbAttr->setOblique(oblique); } catch (...) { } if (!OdZero(tag->getHeightMultiplier()) && !OdZero(tag->getLengthMultiplier())) dbAttr->setWidthFactor(fabs(tag->getLengthMultiplier()) / fabs(tag->getHeightMultiplier())); correctDwgAttributePositionByDgnTagPosition(dbAttr, tag); if (tag->getOffsetUsedFlag()) { matTransform = OdGeMatrix3d::translation(tag->getOffset()); dbAttr->transformBy(matTransform); } dbAttr->adjustAlignment(owner->database()); } //--------------------------------------------------------------------------------------------------- void createTextFromTag(OdDgTagElement* tag, const OdString& strAltTagString, OdDgElementId idSharedCellLevel, OdDbBlockTableRecord* owner) { OdString strText = getTagValue(tag); if( strText.isEmpty() ) return; if (tag->getFreezeGroup() != 0) return; // Try to export tag as text. OdDbTextPtr dbTxt = OdDbText::createObject(); dbTxt->setDatabaseDefaults(owner->database()); owner->database()->addOdDbObject(dbTxt, owner->objectId()); copyEntityProperties(tag, dbTxt); if( !idSharedCellLevel.isNull() ) { if( !OdDgnImportContext::getLockLevelFlag() ) idSharedCellLevel = OdDgnImportContext::getLevelOverride(idSharedCellLevel); OdDbObjectId layerId = OdDgnImportContext::getObjectId(idSharedCellLevel); if (layerId.isNull()) layerId = OdDgnImportContext::getViewportLayer(idSharedCellLevel); if (OdDgnImportContext::getLayerByBlockMode() || layerId.isNull() || OdDbLayerTableRecord::cast(layerId.openObject()).isNull()) layerId = owner->database()->getLayerZeroId(); dbTxt->setLayer(layerId); } owner->appendOdDbEntity(dbTxt); setTextStyle(tag, dbTxt); OdDgElementId idAssociatedElm = tag->getAssociationId(); if( idAssociatedElm.isNull() && !tag->getAssociatedFlag() ) strText = strAltTagString; OdDgFontTableRecordPtr pFontRec = tag->database()->getFontTable(OdDg::kForRead)->getFont(tag->getFontEntryId()); if (pFontRec.isNull() || pFontRec->getType() == kFontTypeRsc) // default Char_Fast_Font font if rsc too strText = convertTextSymbolsFromRscToShx(tag->database(), strText, pFontRec); if(tag->getUnderlineFlag()) { strText = L"%%u" + strText; } if(tag->getOverlineFlag()) { strText = L"%%o" + strText; } dbTxt->setTextString(strText); dbTxt->setHeight(fabs(tag->getHeightMultiplier())); if (tag->getHeightMultiplier() < 0) dbTxt->mirrorInY(true); if (tag->getLengthMultiplier() < 0) dbTxt->mirrorInX(true); OdGeMatrix3d matTransform; if (tag->get3dFormatFlag()) { matTransform = tag->getRotation3d().getMatrix(); matTransform.transposeIt(); } else { matTransform = OdGeMatrix3d::rotation(tag->getRotation2d(), OdGeVector3d::kZAxis); } dbTxt->transformBy(matTransform); setTextJustification(dbTxt, tag->getJustification()); { //There are dgn files with invalid oblique angle double oblique = tag->getSlant(); oblique -= floor(oblique / Oda2PI)*Oda2PI; if (oblique >= OdaPI) oblique -= Oda2PI; if (fabs(oblique) <= OdaToRadian(85.)) dbTxt->setOblique(oblique); } if (!OdZero(tag->getHeightMultiplier()) && !OdZero(tag->getLengthMultiplier())) dbTxt->setWidthFactor(fabs(tag->getLengthMultiplier()) / fabs(tag->getHeightMultiplier())); if (dbTxt->verticalMode() == OdDb::kTextBase && dbTxt->horizontalMode() == OdDb::kTextLeft) dbTxt->setPosition(tag->getOrigin()); else dbTxt->setAlignmentPoint(tag->getOrigin()); if (tag->getOffsetUsedFlag()) { matTransform = OdGeMatrix3d::translation(tag->getOffset()); dbTxt->transformBy(matTransform); } dbTxt->adjustAlignment(owner->database()); } //--------------------------------------------------------------------------------------------------- void OdDgTagImportPE::subImportElement(OdDgElement* e, OdDbBlockTableRecord* owner) { OdDgTagElement* tag = (OdDgTagElement*)e; // Skip binary tags. if (tag->getDataType() == OdDgTagDefinition::kBinary) return; // Get tag definition OdDgElementId idTagSet; OdUInt16 uTagDef; tag->getTagDefinitionId(idTagSet, uTagDef); OdDgTagDefinitionPtr pDgTagDef; if (!idTagSet.isNull()) { OdDgTagDefinitionSetPtr pDgTagSet = idTagSet.openObject(OdDg::kForRead); if (!pDgTagSet.isNull()) pDgTagDef = pDgTagSet->getByEntryId(uTagDef); } // Check tag owner element to create attribute definition, attribute or text. OdDbBlockTableRecord* pOwnerForAttributeDefinition = owner; bool bCreateDefinition = false; bool bCreateAttribute = true; bool bAllowToCreateDefinition = true; OdDgElementId idDgTagOwner = tag->ownerId(); OdDgElementId idDgTagAssociatedId = tag->getAssociationId(); while (!idDgTagOwner.isNull()) { OdDgElementPtr pDgTagOwner = idDgTagOwner.openObject(OdDg::kForRead); if( pDgTagOwner->isKindOf(OdDgModel::desc()) ) break; else if (pDgTagOwner->isKindOf(OdDgSharedCellDefinition::desc())) { bCreateDefinition = true; bCreateAttribute = false; break; } else bAllowToCreateDefinition = false; idDgTagOwner = pDgTagOwner->ownerId(); } if (idDgTagOwner.isNull() || (bCreateDefinition && !bAllowToCreateDefinition)) return; // Check association of tag OdDbObjectId idTagOwner; OdDbBlockTableRecordPtr pCellBlock; if( !idDgTagAssociatedId.isNull() && !bCreateDefinition ) { idTagOwner = OdDgnImportContext::getObjectId(idDgTagAssociatedId); if (!idTagOwner.isNull()) { if (!isTagIntoSharedCell(idDgTagAssociatedId, tag)) { if( isTagAssociatedWithCellHeader(idDgTagAssociatedId, tag, pCellBlock, idTagOwner) ) { pOwnerForAttributeDefinition = pCellBlock.get(); bCreateDefinition = true; bCreateAttribute = true; } else idTagOwner = 0; } } } // Create definition if( bCreateDefinition ) { if (!createAttributeDefinition(tag, pDgTagDef, pOwnerForAttributeDefinition)) return; } // Create attribute. if( bCreateAttribute ) { if(idTagOwner.isErased() || idTagOwner.isNull()) { if( !pDgTagDef.isNull() ) { OdDgElementId idSharedCellLevel; if (!idDgTagAssociatedId.isNull()) { OdDgElementPtr pAssociatedElm = idDgTagAssociatedId.openObject(OdDg::kForRead); if (!pAssociatedElm.isNull() && pAssociatedElm->isKindOf(OdDgSharedCellReference::desc())) { OdDgSharedCellReferencePtr pAssocSharedCell = pAssociatedElm; idSharedCellLevel = pAssocSharedCell->getLevelId(); } } OdString strAltTagString = pDgTagDef->getName(); createTextFromTag(tag, strAltTagString, idSharedCellLevel, owner); } return; } OdDbBlockReferencePtr ownerBlockRef = OdDbBlockReference::cast(idTagOwner.openObject(OdDb::kForWrite)); if (ownerBlockRef.isNull()) return; createAttribute(tag, pDgTagDef, ownerBlockRef, owner); } } }