Compare commits

..

21 Commits

Author SHA1 Message Date
1e05ab9acb for bug #70264 2026-02-04 22:33:00 +03:00
c822a995c1 Merge pull request 'Fix bugs' (#641) from fix/bug-72703 into release/v9.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/641
2026-02-04 14:04:36 +00:00
2d6382e61a Fix bug #79797 2026-02-04 16:51:54 +03:00
024a5e0192 Merge pull request 'Fix pdf bugs' (#640) from fix/pdf-bugs into release/v9.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/640
2026-02-04 11:26:56 +00:00
a6183fa4cd Fix bug 79336 2026-02-04 11:18:47 +03:00
13912c93ef Fix different FontKey 2026-02-04 10:54:57 +03:00
adcdbc164f Fix buid 2026-02-04 10:18:35 +03:00
a48a78c1c5 Merge pull request 'Fix clipRect clear' (#639) from fix/bug-79522 into release/v9.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/639
2026-02-03 20:01:10 +00:00
da57bd115c Fix clipRect clear 2026-02-03 22:46:34 +03:00
5fbb998524 For bug 79437 2026-02-03 18:15:35 +03:00
ea47a90763 Merge pull request 'fix/bug79616' (#637) from fix/bug79554 into release/v9.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/637
2026-02-03 13:16:49 +00:00
daefd8744a Merge pull request 'Fix repeat font name' (#638) from fix/pdf-font into release/v9.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/638
2026-02-03 12:30:38 +00:00
647327a0c5 Fix repeat font name 2026-02-03 15:12:56 +03:00
58b221f4fa fix/bug79616
for bug #79616
2026-02-03 13:31:14 +03:00
858c2e14c8 Fix bug #79697 2026-02-02 20:54:26 +03:00
2024302fbe Merge pull request 'Fix bug 79443' (#617) from fix/bug-79443 into release/v9.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/617
2026-02-02 17:42:29 +00:00
00f4752dda Fix bug #72703 2026-02-02 18:36:03 +03:00
d286b8459b Add offset for unexisted symbol (last width) 2026-02-02 15:36:07 +03:00
ff93f1e8b3 Merge pull request 'Fix bug #79712' (#636) from fix/bug-79712 into release/v9.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/636
2026-02-02 11:08:52 +00:00
4471940b92 Fix bug #79712 2026-01-31 18:26:05 +03:00
2a3f565b44 Fix bug 79443 2026-01-22 01:53:25 +03:00
32 changed files with 234 additions and 149 deletions

View File

@ -600,12 +600,6 @@ namespace NSCSS
return true;
}
void CColor::SetNone()
{
Clear();
m_oValue.reset();
}
char NormalizeNegativeColorValue(INT nValue)
{
@ -647,18 +641,21 @@ namespace NSCSS
}
else if (L"none" == wsNewValue || wsNewValue == L"transparent")
{
SetNone();
Clear();
m_oValue = CColorValue();
bResult = true;
}
else if (L"context-stroke" == wsNewValue)
{
Clear();
m_oValue = CColorValueContextStroke();
bResult = true;
}
else if (L"context-fill" == wsNewValue)
{
Clear();
m_oValue = CColorValueContextFill();
bResult = true;
}
else if (10 <= wsNewValue.length() && wsNewValue.substr(0, 3) == L"rgb")
{

View File

@ -343,7 +343,6 @@ namespace NSCSS
void SetRGB(const TRGB& oRGB);
void SetHEX(const std::wstring& wsValue);
bool SetUrl(const std::wstring& wsValue);
void SetNone();
};
typedef enum

View File

@ -85,6 +85,13 @@ bool Segment::IsEmpty() const noexcept
return Id == 0 && Index == -1 && P.IsZero() && HI.IsZero() && HO.IsZero();
}
bool Segment::Equals(const Segment& other) const noexcept
{
return isZero(P.X - other.P.X) && isZero(P.Y - other.P.Y) &&
isZero(HI.X - other.HI.X) && isZero(HI.Y - other.HI.Y) &&
isZero(HO.X - other.HO.X) && isZero(HO.Y - other.HO.Y);
}
bool Segment::operator==(const Segment& other) const noexcept
{
return (Index == other.Index) && (Id == other.Id);
@ -690,6 +697,12 @@ bool Curve::IsStraight() const noexcept
return !Segment2.IsCurve;
}
bool Curve::Equals(const Curve& other) const noexcept
{
return Segment1.Equals(other.Segment1) &&
Segment2.Equals(other.Segment2);
}
bool Curve::operator==(const Curve& other) const noexcept
{
return Segment1 == other.Segment1 &&
@ -830,7 +843,7 @@ void CBooleanOperations::TraceBoolean()
return;
}
if (!Locations.empty())
if (!Locations.empty() && !IsOnlyEnds())
{
int length = static_cast<int>(Locations.size());
for (int i = 0; i < length; i++)
@ -1845,7 +1858,7 @@ void CBooleanOperations::GetCurveIntersection(const Curve& curve1, const Curve&
AddCurveIntersection(flip ? curve2 : curve1, flip ? curve1 : curve2,
flip ? curve2 : curve1, flip ? curve1 : curve2, flip);
if (Locations.size() == before && (!straight || Locations.empty()))
if (Locations.size() == before && (!straight /*|| Locations.empty()*/))
{
double t = curve2.GetTimeOf(curve1.Segment1.P);
if (t != -1.0)
@ -2058,17 +2071,27 @@ bool CBooleanOperations::IsInside(const Segment& segment) const
void CBooleanOperations::SetWinding()
{
if (Locations.empty() || (Locations.size() == 2 && Locations[0]->Ends))
if (Locations.empty() || (Locations.size() == 2 && Locations[0]->Ends) || IsOnlyEnds())
{
Segment s1, s2;
Segment s1 = Segments1[0], s2 = Segments2[0];
for (const auto& s : Segments1)
if (!s.Inters)
{
bool skip = false;
for (const auto& ss : Segments2)
skip = skip || !s.Equals(ss);
if (!s.Inters && !skip)
s1 = s;
}
for (const auto& s : Segments2)
if (!s.Inters)
{
bool skip = false;
for (const auto& ss : Segments1)
skip = skip || !s.Equals(ss);
if (!s.Inters && !skip)
s2 = s;
}
bool winding = IsInside(s1);
@ -2285,8 +2308,8 @@ bool CBooleanOperations::IsOneCurvePath(int pathIndex) const noexcept
void CBooleanOperations::AddLocation(Curve curve1, Curve curve2, double t1,
double t2, bool overlap, bool filter, bool ends)
{
bool excludeStart = !overlap && GetPreviousCurve(curve1) == curve2,
excludeEnd = !overlap && curve1 != curve2 && GetNextCurve(curve1) == curve2;
bool excludeStart = !overlap && GetPreviousCurve(curve1).Equals(curve2),
excludeEnd = !overlap && curve1 != curve2 && GetNextCurve(curve1).Equals(curve2);
double tMin = CURVETIME_EPSILON,
tMax = 1 - tMin;
@ -2345,6 +2368,18 @@ bool CBooleanOperations::CheckLocation(std::shared_ptr<Location> loc, bool start
return false;
}
bool CBooleanOperations::IsOnlyEnds() const noexcept
{
bool onlyEnds1 = true;
bool onlyEnds2 = true;
for (const auto& l : Locations)
{
onlyEnds1 = onlyEnds1 && l->Ends;
onlyEnds2 = onlyEnds2 && l->Inters->Ends;
}
return onlyEnds1 || onlyEnds2;
}
CGraphicsPath CalcBooleanOperation(const CGraphicsPath& path1,
const CGraphicsPath& path2,
BooleanOpType op,

View File

@ -37,6 +37,7 @@ namespace Aggplus
bool IsValid(const BooleanOpType& op) const noexcept;
bool IsEmpty() const noexcept;
bool Equals(const Segment& other) const noexcept;
bool operator==(const Segment& other) const noexcept;
bool operator!=(const Segment& other) const noexcept;
};
@ -82,6 +83,7 @@ namespace Aggplus
void Flip() noexcept;
bool IsStraight() const noexcept;
bool Equals(const Curve& other) const noexcept;
bool operator==(const Curve& other) const noexcept;
bool operator!=(const Curve& other) const noexcept;
};
@ -159,6 +161,7 @@ namespace Aggplus
bool IsOneCurvePath(int pathIndex) const noexcept;
void AddOffsets(std::vector<double>& offsets, const Curve& curve, bool end);
bool CheckLocation(std::shared_ptr<Location> loc, bool start) const noexcept;
bool IsOnlyEnds() const noexcept;
private:
BooleanOpType Op = Intersection;

View File

@ -498,7 +498,10 @@ namespace NSOnlineOfficeBinToPdf
bIsEnableBrushRect = oReader.ReadBool();
if (!bIsEnableBrushRect)
{
pRenderer->BrushRect(bIsEnableBrushRect ? 1 : 0, 0, 0, 1, 1);
clipRect = Aggplus::RectF_T<double>();
}
break;
}
case ctBrushTexturePathOld:
@ -770,7 +773,6 @@ namespace NSOnlineOfficeBinToPdf
clipPath.AddRectangle(clipRect.X, clipRect.Y, clipRect.Width, clipRect.Height);
path = Aggplus::CalcBooleanOperation(drawPath, clipPath, Aggplus::Intersection);
clipRect = Aggplus::RectF_T<double>();
}
pRenderer->AddPath(path);

View File

@ -74,7 +74,7 @@ namespace MetaFile
virtual void EndClipPath(unsigned int unMode) = 0;
virtual void UpdateDC() = 0;
virtual void SetTransform(double& dM11, double& dM12, double& dM21, double& dM22, double& dX, double& dY) = 0;
virtual void SetTransform(const double& dM11, const double& dM12, const double& dM21, const double& dM22, const double& dX, const double& dY) = 0;
virtual void GetTransform(double* pdM11, double* pdM12, double* pdM21, double* pdM22, double* pdX, double* pdY) = 0;
};

View File

@ -863,12 +863,17 @@ namespace MetaFile
void PathClip(const CPath& oPath, int nClipMode, TXForm *pTransform = NULL)
{
double dM11, dM12, dM21, dM22, dX, dY;
GetTransform(&dM11, &dM12, &dM21, &dM22, &dX, &dY);
if (NULL != pTransform)
{
GetTransform(&dM11, &dM12, &dM21, &dM22, &dX, &dY);
SetTransform(pTransform->M11, pTransform->M12, pTransform->M21, pTransform->M22, pTransform->Dx, pTransform->Dy);
}
SetTransform(pTransform->M11, pTransform->M12,
pTransform->M21, pTransform->M22,
pTransform->Dx - m_pFile->GetDCBounds().Left,
pTransform->Dy - m_pFile->GetDCBounds().Top);
else
SetTransform(dM11, dM12, dM21, dM22,
dX - m_pFile->GetDCBounds().Left,
dY - m_pFile->GetDCBounds().Top);
oPath.DrawOn(this, false, false, nClipMode);
@ -914,7 +919,7 @@ namespace MetaFile
m_bStartedPath = false;
}
void SetTransform(double& dM11, double& dM12, double& dM21, double& dM22, double& dX, double& dY)
void SetTransform(const double& dM11, const double& dM12, const double& dM21, const double& dM22, const double& dX, const double& dY)
{
double dKoefX = m_dScaleX;
double dKoefY = m_dScaleY;

View File

@ -239,7 +239,7 @@ namespace MetaFile
void EndClipPath(unsigned int unMode) override {};
void UpdateDC() override {};
void SetTransform(double& dM11, double& dM12, double& dM21, double& dM22, double& dX, double& dY) override {};
void SetTransform(const double& dM11, const double& dM12, const double& dM21, const double& dM22, const double& dX, const double& dY) override {};
void GetTransform(double* pdM11, double* pdM12, double* pdM21, double* pdM22, double* pdX, double* pdY) override {};
};
}

View File

@ -182,7 +182,7 @@ namespace MetaFile
pInterpretator->UpdateDC();
}
void CEmfInterpretatorArray::SetTransform(double &dM11, double &dM12, double &dM21, double &dM22, double &dX, double &dY)
void CEmfInterpretatorArray::SetTransform(const double &dM11, const double &dM12, const double &dM21, const double &dM22, const double &dX, const double &dY)
{
for (CEmfInterpretatorBase* pInterpretator : m_arInterpretators)
pInterpretator->SetTransform(dM11, dM12, dM21, dM22, dX, dY);

View File

@ -57,7 +57,7 @@ namespace MetaFile
void EndClipPath(unsigned int unMode) override;
void UpdateDC() override;
void SetTransform(double& dM11, double& dM12, double& dM21, double& dM22, double& dX, double& dY) override;
void SetTransform(const double& dM11, const double& dM12, const double& dM21, const double& dM22, const double& dX, const double& dY) override;
void GetTransform(double* pdM11, double* pdM12, double* pdM21, double* pdM22, double* pdX, double* pdY) override;
void HANDLE_EMR_HEADER(const TEmfHeader& oTEmfHeader) override;

View File

@ -143,7 +143,7 @@ namespace MetaFile
m_pMetaFileRenderer->UpdateDC();
}
void CEmfInterpretatorRender::SetTransform(double &dM11, double &dM12, double &dM21, double &dM22, double &dX, double &dY)
void CEmfInterpretatorRender::SetTransform(const double& dM11, const double& dM12, const double& dM21, const double& dM22, const double& dX, const double& dY)
{
if (NULL != m_pMetaFileRenderer)
m_pMetaFileRenderer->SetTransform(dM11, dM12, dM21, dM22, dX, dY);

View File

@ -43,7 +43,7 @@ namespace MetaFile
void EndClipPath(unsigned int unMode) override;
void UpdateDC() override;
void SetTransform(double& dM11, double& dM12, double& dM21, double& dM22, double& dX, double& dY) override;
void SetTransform(const double& dM11, const double& dM12, const double& dM21, const double& dM22, const double& dX, const double& dY) override;
void GetTransform(double* pdM11, double* pdM12, double* pdM21, double* pdM22, double* pdX, double* pdY) override;
CMetaFileRenderer* GetRenderer() const;

View File

@ -223,7 +223,7 @@ namespace MetaFile
void EndPath() override {};
void UpdateDC() override {};
void SetTransform(double& dM11, double& dM12, double& dM21, double& dM22, double& dX, double& dY) override {};
void SetTransform(const double& dM11, const double& dM12, const double& dM21, const double& dM22, const double& dX, const double& dY) override {};
void GetTransform(double* pdM11, double* pdM12, double* pdM21, double* pdM22, double* pdX, double* pdY) override {};
void SwapClips(CSvgClip& oFirstClip, CSvgClip& oSecondClip);

View File

@ -237,7 +237,7 @@ namespace MetaFile
void EndClipPath(unsigned int unMode) override {};
void UpdateDC() override {};
void SetTransform(double& dM11, double& dM12, double& dM21, double& dM22, double& dX, double& dY) override {};
void SetTransform(const double& dM11, const double& dM12, const double& dM21, const double& dM22, const double& dX, const double& dY) override {};
void GetTransform(double* pdM11, double* pdM12, double* pdM21, double* pdM22, double* pdX, double* pdY) override {};
};
}

View File

@ -627,13 +627,21 @@ namespace MetaFile
void CInterpretatorSvgBase::PathClip(const CPath &oPath, int nClipMode, TXForm *pTransform)
{
std::wstring wsPath = CreatePath(oPath, pTransform);
const std::wstring wsPath = CreatePath(oPath, pTransform);
if (wsPath.empty())
return;
const std::wstring wsClipId = L"PATHCLIP_" + ConvertToWString(++m_unNumberDefs, 0);
const std::wstring wsValue = L"<path d=\"" + wsPath + L"\"/>";
std::wstring wsValue = L"<path d=\"" + wsPath + L"\"";
const int nOffsetLeft{-m_pParser->GetDCBounds().Left};
const int nOffsetTop {-m_pParser->GetDCBounds().Top};
if (0 != nOffsetLeft || 0 != nOffsetTop)
wsValue += L" transform=\"translate(" + std::to_wstring(nOffsetLeft) + L',' + std::to_wstring(nOffsetTop) + L")\"";
wsValue += L"/>";
m_oClip.AddClipValue(wsClipId, wsValue, nClipMode);
}

View File

@ -131,7 +131,7 @@ namespace MetaFile
m_pMetaFileRenderer->UpdateDC();
}
void CWmfInterpretatorRender::SetTransform(double &dM11, double &dM12, double &dM21, double &dM22, double &dX, double &dY)
void CWmfInterpretatorRender::SetTransform(const double& dM11, const double& dM12, const double& dM21, const double& dM22, const double& dX, const double& dY)
{
if (NULL != m_pMetaFileRenderer)
m_pMetaFileRenderer->SetTransform(dM11, dM12, dM21, dM22, dX, dY);

View File

@ -40,7 +40,7 @@ namespace MetaFile
void EndClipPath(unsigned int unMode) override;
void UpdateDC() override;
void SetTransform(double& dM11, double& dM12, double& dM21, double& dM22, double& dX, double& dY) override;
void SetTransform(const double& dM11, const double& dM12, const double& dM21, const double& dM22, const double& dX, const double& dY) override;
void GetTransform(double* pdM11, double* pdM12, double* pdM21, double* pdM22, double* pdX, double* pdY) override;
CMetaFileRenderer* GetRenderer() const;

View File

@ -130,7 +130,7 @@ namespace MetaFile
void EndClipPath(unsigned int unMode) override {};
void UpdateDC() override {};
void SetTransform(double& dM11, double& dM12, double& dM21, double& dM22, double& dX, double& dY) override {};
void SetTransform(const double& dM11, const double& dM12, const double& dM21, const double& dM22, const double& dX, const double& dY) override {};
void GetTransform(double* pdM11, double* pdM12, double* pdM21, double* pdM22, double* pdX, double* pdY) override {};
};

View File

@ -358,7 +358,7 @@ namespace SVG
bool CRenderedObject::ApplyStroke(IRenderer *pRenderer, const TStroke *pStroke, bool bUseDefault, const CRenderedObject* pContextObject) const
{
if (NULL == pRenderer || NULL == pStroke || NSCSS::NSProperties::EColorType::ColorNone == pStroke->m_oColor.GetType() || (!bUseDefault && ((pStroke->m_oWidth.Empty() || pStroke->m_oWidth.Zero()) && pStroke->m_oColor.Empty())))
if (NULL == pRenderer || NULL == pStroke || pStroke->m_oColor.None() || (!bUseDefault && ((pStroke->m_oWidth.Empty() || pStroke->m_oWidth.Zero()) && pStroke->m_oColor.Empty())))
{
pRenderer->put_PenSize(0);
return false;
@ -401,7 +401,7 @@ namespace SVG
bool CRenderedObject::ApplyFill(IRenderer *pRenderer, const NSCSS::NSProperties::CColor *pFill, const CSvgFile *pFile, bool bUseDefault, const CRenderedObject* pContextObject) const
{
if (NULL == pRenderer || NULL == pFill || NSCSS::NSProperties::EColorType::ColorNone == pFill->GetType() || (!bUseDefault && pFill->Empty()))
if (NULL == pRenderer || NULL == pFill || pFill->None() || (!bUseDefault && pFill->Empty()))
{
pRenderer->put_BrushType(c_BrushTypeNoFill);
return false;

View File

@ -105,13 +105,13 @@ namespace NSHeif {
inline bool CHeifFile::Decode(heif_context* ctx, CBgraFrame* frame, bool isRGBA)
{
heif_image_handle* handle;
heif_image_handle* handle = nullptr;
defer(heif_image_handle_release(handle););
if (IsError(heif_context_get_primary_image_handle(ctx, &handle)))
return false;
heif_image* img;
heif_image* img = nullptr;
defer(heif_image_release(img););
if (IsError(heif_decode_image(handle, &img, heif_colorspace_RGB, heif_chroma_444, nullptr)))

View File

@ -555,6 +555,9 @@ namespace NSDocxRenderer
std::wstring origin_lefts{};
for (auto& l : m_arOriginLefts)
origin_lefts += std::to_wstring(static_cast<int>(l * c_dMMToEMU)) + L";";
// add offset for last symbol
if (!m_arSymWidths.empty())
origin_lefts += std::to_wstring(static_cast<int>((m_arOriginLefts.back() + m_arSymWidths.back()) * c_dMMToEMU)) + L";";
oWriter.WriteBYTE(5); oWriter.WriteStringUtf16(origin_lefts); // Origin lefts
oWriter.WriteBYTE(6); oWriter.WriteBool(m_bFontSubstitution); // Font Substitution (just pass from pdf)

View File

@ -1261,12 +1261,10 @@ void CConverter2OOXML::WriteEqEditShape(const CCtrlEqEdit* pEqEditShape, short s
OpenParagraph(shParaShapeID, shParaStyleID, oBuilder, oState);
oBuilder.WriteString(L"<w:r><w:t xml:space=\"preserve\">");
oBuilder.WriteString(L"<w:r/>");
StarMath::CStarMathConverter oConverterStarMath;
oBuilder.WriteString(oConverterStarMath.ConvertEQNToOOXml(pEqEditShape->GetEqn()));
oBuilder.WriteString(L"</w:t></w:r>");
}
void CConverter2OOXML::WriteOleShape(const CCtrlShapeOle* pOleShape, short shParaShapeID, short shParaStyleID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState)

View File

@ -192,7 +192,7 @@ namespace OOX
L"diagrams/data", true, true);
const FileType DiagramQuickStyle(L"diagrams", L"quickStyle.xml",
L"application/vnd.openxmlformats-officedocument.drawingml.diagramQuickStyle+xml",
L"application/vnd.openxmlformats-officedocument.drawingml.diagramStyle+xml",
L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/diagramQuickStyle",
L"diagrams/quickStyle", true, true);

View File

@ -2083,7 +2083,7 @@ int docx_conversion_context::process_paragraph_style(_CP_OPT(std::wstring) style
else
{
const std::wstring id = styles_map_.get( styleInst->name(), styleInst->type() );
output_stream() << L"<w:pPr>";
output_stream() << L"<w:pPr>";
output_stream() << L"<w:pStyle w:val=\"" << id << L"\" />";
@ -2315,7 +2315,7 @@ void docx_conversion_context::process_page_break_after(const odf_reader::style_i
if (inst->content() && inst->content()->get_style_paragraph_properties())
{
_CP_OPT(odf_types::fo_break) fo_break_val = inst->content()->get_style_paragraph_properties()->content_.fo_break_after_;
if (fo_break_val)
if (fo_break_val)
{
set_page_break_after(fo_break_val->get_type());
break;

View File

@ -672,8 +672,12 @@ void _oox_drawing::serialize_bodyPr(std::wostream & strm, const std::wstring & n
_CP_OPT(int) iWrap;
odf_reader::GetProperty(prop, L"text-wrap", iWrap);
if (((iWrap) && (*iWrap == 0)) || ((is_math_formula) && (*is_math_formula)))
if (((iWrap) && (*iWrap == 0))) // для текста устанавливаем значение square. Так у нас визуальное соотвествие при конвертации
CP_XML_ATTR(L"wrap", L"square");
else if((is_math_formula) && (*is_math_formula))
{
CP_XML_ATTR(L"wrap", L"none");
}
}
}

View File

@ -366,7 +366,7 @@ void line_break::docx_convert(oox::docx_conversion_context & Context)
{
bool in_drawing = false;
if (Context.get_drawing_context().get_current_shape() || Context.get_drawing_context().get_current_frame())
if (Context.get_drawing_context().get_current_shape() || Context.get_drawing_context().get_current_frame())
{
in_drawing = true;

View File

@ -4350,14 +4350,14 @@ void CPdfEditor::ScanAndProcessFonts(PDFDoc* pPDFDocument, XRef* xref, Dict* pRe
{
Ref oEmbRef;
std::wstring wsFontBaseName = NSStrings::GetStringFromUTF32(gfxFont->getName());
if (gfxFont->getEmbeddedFontID(&oEmbRef) || PdfReader::IsBaseFont(wsFontBaseName))
GfxFontLoc* pFontLoc = NULL;
if (gfxFont->getEmbeddedFontID(&oEmbRef) || PdfReader::IsBaseFont(wsFontBaseName) || ((pFontLoc = gfxFont->locateFont(xref, false)) && NSStrings::GetStringFromUTF32(pFontLoc->path).length()))
{
std::wstring wsFileName, wsFontName;
PdfReader::RendererOutputDev::GetFont(xref, pFontManager, pFontList, gfxFont, wsFileName, wsFontName, false);
// Собираем информацию о встроенном шрифте
if (gfxFont->getEmbeddedFontID(&oEmbRef) && !PdfReader::IsBaseFont(wsFontBaseName))
if (!PdfReader::IsBaseFont(wsFontBaseName))
{
PdfReader::TFontEntry pFontEntry;
Ref nFontRef = oFontRef.getRef();
@ -4384,6 +4384,7 @@ void CPdfEditor::ScanAndProcessFonts(PDFDoc* pPDFDocument, XRef* xref, Dict* pRe
}
}
RELEASEOBJECT(pFontLoc);
RELEASEOBJECT(gfxFont);
}

View File

@ -1072,12 +1072,30 @@ HRESULT CPdfFile::put_FontName(const std::wstring& wsName)
}
m_pInternal->pWriter->AddFont(wsFont, bBold, bItalic, wsFontPath, 0);
}
else
else if (wsFontPath.empty())
{
const std::map<std::wstring, std::wstring>& mFonts = m_pInternal->pReader->GetFonts();
auto it = mFonts.find(sSub);
if (it != mFonts.end())
wsFontPath = it->second;
size_t lastSpace = wsName.find_last_of(L' ');
if (lastSpace != std::wstring::npos)
{
std::wstring numberStr = wsName.substr(lastSpace + 1);
int nTargetCode = std::stoi(numberStr);
const std::map<std::wstring, std::wstring>& mFonts = m_pInternal->pReader->GetFonts();
auto it = std::find_if(mFonts.begin(), mFonts.end(), [nTargetCode](const std::pair<const std::wstring, std::wstring>& pair)
{
const std::wstring& key = pair.first;
size_t pos = key.rfind(L' ');
if (pos != std::wstring::npos)
{
int keyCode = std::stoi(key.substr(pos + 1));
return keyCode == nTargetCode;
}
return false;
});
if (it != mFonts.end())
wsFont = L"Embedded: " + it->first;
else
wsFont = wsName.substr(10, lastSpace - 10);
}
else
wsFont = sSub;
}

View File

@ -1461,6 +1461,8 @@ namespace PdfReader
wsFontName = wsFontBaseName;
if (bNotFullName)
EraseSubsetTag(wsFontName);
else
wsFontName += (L" " + std::to_wstring(pFont->getID()->num));
pEntry->wsFilePath = wsFileName;
pEntry->wsFontName = wsFontName;

View File

@ -901,7 +901,10 @@ namespace PdfWriter
{
CFontEmbedded* pFont = FindFontEmbedded(wsFontPath, unIndex);
if (pFont)
{
pFont->UpdateKey(sFontKey);
return pFont;
}
pFont = new CFontEmbedded(m_pXref, this);
pFont->LoadFont(sFontKey, nType, mCodeToWidth, mCodeToUnicode, mCodeToGID);
m_vFontsEmbedded.push_back(TFontInfo(wsFontPath, unIndex, pFont));

View File

@ -3222,56 +3222,59 @@ namespace PdfWriter
}
// Граница
if (dBorder != 1)
if (pAnnot->HaveBC())
{
m_pStream->WriteReal(dBorder);
m_pStream->WriteStr(" w\012");
}
if (nBorderType == EBorderType::Dashed)
m_pStream->WriteStr(m_pAnnot->GetBorderDash().c_str());
m_pStream->WriteStr(pAnnot->GetBCforAP().c_str());
m_pStream->WriteStr("\012q\012");
m_pStream->WriteStr("1 0 0 1 ");
m_pStream->WriteReal(dCX);
m_pStream->WriteChar(' ');
m_pStream->WriteReal(dCY);
m_pStream->WriteStr(" cm\012");
StreamWriteCircle(m_pStream, 0, 0, dR - dBorder / 2.0);
m_pStream->WriteStr("s\012Q\012");
if (nBorderType == EBorderType::Beveled || nBorderType == EBorderType::Inset)
{
double ca = cos(45.0 / 180.0 * M_PI);
double cx = 0, cy = 0, r = dR - dBorder * 1.5;
double bezierCircle = 0.55228475 * r;
std::string sBG = pAnnot->GetBGforAP(-0.250977, true);
if (sBG.empty())
sBG = "0.749023 G";
if (nBorderType == EBorderType::Inset)
m_pStream->WriteStr(bN ? "0.501953 G" : "0 G");
else // Beveled
m_pStream->WriteStr(bN ? "1 G" : sBG.c_str());
if (dBorder != 1)
{
m_pStream->WriteReal(dBorder);
m_pStream->WriteStr(" w\012");
}
if (nBorderType == EBorderType::Dashed)
m_pStream->WriteStr(m_pAnnot->GetBorderDash().c_str());
m_pStream->WriteStr(pAnnot->GetBCforAP().c_str());
m_pStream->WriteStr("\012q\012");
StreamWriteCM(m_pStream, ca, ca, -ca, ca, dCX, dCY);
StreamWriteXYMove(m_pStream, cx + r, cy);
StreamWriteXYCurve(m_pStream, cx + r, cy + bezierCircle, cx + bezierCircle, cy + r, cx, cy + r);
StreamWriteXYCurve(m_pStream, cx - bezierCircle, cy + r, cx - r, cy + bezierCircle, cx - r, cy);
m_pStream->WriteStr("S\012Q\012");
m_pStream->WriteStr("1 0 0 1 ");
m_pStream->WriteReal(dCX);
m_pStream->WriteChar(' ');
m_pStream->WriteReal(dCY);
m_pStream->WriteStr(" cm\012");
if (nBorderType == EBorderType::Inset)
m_pStream->WriteStr(bN ? "0.75293 G" : "1 G");
else // Beveled
m_pStream->WriteStr(bN ? sBG.c_str() : "1 G");
StreamWriteCircle(m_pStream, 0, 0, dR - dBorder / 2.0);
m_pStream->WriteStr("s\012Q\012");
m_pStream->WriteStr("\012q\012");
StreamWriteCM(m_pStream, ca, ca, -ca, ca, dCX, dCY);
StreamWriteXYMove(m_pStream, cx - r, cy);
StreamWriteXYCurve(m_pStream, cx - r, cy - bezierCircle, cx - bezierCircle, cy - r, cx, cy - r);
StreamWriteXYCurve(m_pStream, cx + bezierCircle, cy - r, cx + r, cy - bezierCircle, cx + r, cy);
m_pStream->WriteStr("S\012Q\012");
if (nBorderType == EBorderType::Beveled || nBorderType == EBorderType::Inset)
{
double ca = cos(45.0 / 180.0 * M_PI);
double cx = 0, cy = 0, r = dR - dBorder * 1.5;
double bezierCircle = 0.55228475 * r;
std::string sBG = pAnnot->GetBGforAP(-0.250977, true);
if (sBG.empty())
sBG = "0.749023 G";
if (nBorderType == EBorderType::Inset)
m_pStream->WriteStr(bN ? "0.501953 G" : "0 G");
else // Beveled
m_pStream->WriteStr(bN ? "1 G" : sBG.c_str());
m_pStream->WriteStr("\012q\012");
StreamWriteCM(m_pStream, ca, ca, -ca, ca, dCX, dCY);
StreamWriteXYMove(m_pStream, cx + r, cy);
StreamWriteXYCurve(m_pStream, cx + r, cy + bezierCircle, cx + bezierCircle, cy + r, cx, cy + r);
StreamWriteXYCurve(m_pStream, cx - bezierCircle, cy + r, cx - r, cy + bezierCircle, cx - r, cy);
m_pStream->WriteStr("S\012Q\012");
if (nBorderType == EBorderType::Inset)
m_pStream->WriteStr(bN ? "0.75293 G" : "1 G");
else // Beveled
m_pStream->WriteStr(bN ? sBG.c_str() : "1 G");
m_pStream->WriteStr("\012q\012");
StreamWriteCM(m_pStream, ca, ca, -ca, ca, dCX, dCY);
StreamWriteXYMove(m_pStream, cx - r, cy);
StreamWriteXYCurve(m_pStream, cx - r, cy - bezierCircle, cx - bezierCircle, cy - r, cx, cy - r);
StreamWriteXYCurve(m_pStream, cx + bezierCircle, cy - r, cx + r, cy - bezierCircle, cx + r, cy);
m_pStream->WriteStr("S\012Q\012");
}
}
// Установлен
@ -3328,60 +3331,63 @@ namespace PdfWriter
}
// Граница
if (nBorderType == EBorderType::Beveled || nBorderType == EBorderType::Inset)
if (pAnnot->HaveBC())
{
std::string sBG = pAnnot->GetBGforAP(-0.250977);
if (sBG.empty())
sBG = "0.749023 g";
if (nBorderType == EBorderType::Beveled || nBorderType == EBorderType::Inset)
{
std::string sBG = pAnnot->GetBGforAP(-0.250977);
if (sBG.empty())
sBG = "0.749023 g";
if (nBorderType == EBorderType::Inset)
m_pStream->WriteStr(bN ? "0.501953 g" : "0 g");
else // Beveled
m_pStream->WriteStr(bN ? "1 g" : sBG.c_str());
if (nBorderType == EBorderType::Inset)
m_pStream->WriteStr(bN ? "0.501953 g" : "0 g");
else // Beveled
m_pStream->WriteStr(bN ? "1 g" : sBG.c_str());
m_pStream->WriteStr("\012");
StreamWriteXYMove(m_pStream, dBorder, dBorder);
StreamWriteXYLine(m_pStream, dBorder, dH - dBorder);
StreamWriteXYLine(m_pStream, dW - dBorder, dH - dBorder);
StreamWriteXYLine(m_pStream, dW - dBorder * 2.0, dH - dBorder * 2.0);
StreamWriteXYLine(m_pStream, dBorder * 2.0, dH - dBorder * 2.0);
StreamWriteXYLine(m_pStream, dBorder * 2.0, dBorder * 2.0);
m_pStream->WriteStr("f\012");
if (nBorderType == EBorderType::Inset)
m_pStream->WriteStr(bN ? "0.75293 g" : "1 g");
else // Beveled
m_pStream->WriteStr(bN ? sBG.c_str() : "1 g");
m_pStream->WriteStr("\012");
StreamWriteXYMove(m_pStream, dW - dBorder, dH - dBorder);
StreamWriteXYLine(m_pStream, dW - dBorder, dBorder);
StreamWriteXYLine(m_pStream, dBorder, dBorder);
StreamWriteXYLine(m_pStream, dBorder * 2.0, dBorder * 2.0);
StreamWriteXYLine(m_pStream, dW - dBorder * 2.0, dBorder * 2.0);
StreamWriteXYLine(m_pStream, dW - dBorder * 2.0, dH - dBorder * 2.0);
m_pStream->WriteStr("f\012");
}
if (dBorder != 1)
{
m_pStream->WriteReal(dBorder);
m_pStream->WriteStr(" w\012");
}
if (nBorderType == EBorderType::Dashed)
m_pStream->WriteStr(m_pAnnot->GetBorderDash().c_str());
m_pStream->WriteStr(pAnnot->GetBCforAP().c_str());
m_pStream->WriteStr("\012");
StreamWriteXYMove(m_pStream, dBorder, dBorder);
StreamWriteXYLine(m_pStream, dBorder, dH - dBorder);
StreamWriteXYLine(m_pStream, dW - dBorder, dH - dBorder);
StreamWriteXYLine(m_pStream, dW - dBorder * 2.0, dH - dBorder * 2.0);
StreamWriteXYLine(m_pStream, dBorder * 2.0, dH - dBorder * 2.0);
StreamWriteXYLine(m_pStream, dBorder * 2.0, dBorder * 2.0);
m_pStream->WriteStr("f\012");
if (nBorderType == EBorderType::Inset)
m_pStream->WriteStr(bN ? "0.75293 g" : "1 g");
else // Beveled
m_pStream->WriteStr(bN ? sBG.c_str() : "1 g");
m_pStream->WriteStr("\012");
StreamWriteXYMove(m_pStream, dW - dBorder, dH - dBorder);
StreamWriteXYLine(m_pStream, dW - dBorder, dBorder);
StreamWriteXYLine(m_pStream, dBorder, dBorder);
StreamWriteXYLine(m_pStream, dBorder * 2.0, dBorder * 2.0);
StreamWriteXYLine(m_pStream, dW - dBorder * 2.0, dBorder * 2.0);
StreamWriteXYLine(m_pStream, dW - dBorder * 2.0, dH - dBorder * 2.0);
m_pStream->WriteStr("f\012");
if (nBorderType == EBorderType::Underline)
{
StreamWriteXYMove(m_pStream, 0, dBorder / 2.0);
StreamWriteXYLine(m_pStream, dW, dBorder / 2.0);
}
else
StreamWriteRect(m_pStream, dBorder / 2.0, dBorder / 2.0, dW - dBorder, dH - dBorder);
m_pStream->WriteStr("s\012Q\012");
}
if (dBorder != 1)
{
m_pStream->WriteReal(dBorder);
m_pStream->WriteStr(" w\012");
}
if (nBorderType == EBorderType::Dashed)
m_pStream->WriteStr(m_pAnnot->GetBorderDash().c_str());
m_pStream->WriteStr(pAnnot->GetBCforAP().c_str());
m_pStream->WriteStr("\012");
if (nBorderType == EBorderType::Underline)
{
StreamWriteXYMove(m_pStream, 0, dBorder / 2.0);
StreamWriteXYLine(m_pStream, dW, dBorder / 2.0);
}
else
StreamWriteRect(m_pStream, dBorder / 2.0, dBorder / 2.0, dW - dBorder, dH - dBorder);
m_pStream->WriteStr("s\012Q\012");
// Установлен
if (!bSet)
return;

View File

@ -71,6 +71,7 @@ namespace PdfWriter
unsigned int EncodeUnicode(const unsigned int& unGID, const unsigned int& unUnicode);
unsigned int EncodeGID(const unsigned int& unGID);
const char* GetFontKey() const { return m_sFontKey.c_str(); }
void UpdateKey(const std::string& sFontKey) { m_sFontKey = sFontKey; }
private:
std::string m_sFontKey;