A solution that adjusts images in table cells would be too complicated, so the solution below is only for images inside the main document.
First, we need to calculate maximal possible image width.
This demo sets page size according to values specified in DocParameters property, so we can calculate this value in this way:
Code: Select all
function TfrmCustomMakePDF.GetMaxImageWidth: TRVStyleLength;
var
rv: TCustomRichView;
begin
rv := FDocument.MainDoc.RichView;
// page width minus page margins
Result := rv.Style.RVUnitsToUnits(
rv.DocParameters.PageWidth
- rv.DocParameters.LeftMargin - rv.DocParameters.RightMargin,
rv.DocParameters.Units);
// and minus internal margins
dec(Result, rv.Style.StandardPixelsToUnits(rv.LeftMargin + rv.RightMargin));
end;
The returned value is measured in FDocument.MainDoc.RichView.Style.Units (like most sizes in TRichView documents)
Now, the code for adjusting images. It is large because it takes into account all possible values that affect maximal width (including border and spacing around images, indents of paragraphs and lists).
The code resizes large images proportionally.
Code: Select all
procedure TfrmCustomMakePDF.AdjustImages;
var
rv: TCustomRichView;
MaxWidth, ImgWidth, ImgHeight, ExtraWidth, BorderWidth, ImgPadding, ImgMargin: TRVStyleLength;
i: Integer;
ImgName: TRVUnicodeString;
Gr: TGraphic;
VAlign: TRVVAlign;
ImgTag: TRVTag;
ListItemNo, ListNo, ListLevel, ListStartFrom: Integer;
ListReset: Boolean;
ParaStyle: TParaInfo;
begin
MaxWidth := GetMaxImageWidth;
rv := FDocument.MainDoc.RichView;
for i := 0 to rv.ItemCount - 1 do
if rv.GetItem(i) is TRVGraphicItemInfo then
begin
rv.GetPictureInfo(i, ImgName, Gr, VAlign, ImgTag);
// getting image width (resized or original)
rv.GetItemExtraIntProperty(i, rvepImageWidth, Integer(ImgWidth));
if ImgWidth <= 0 then
ImgWidth := rv.Style.StandardPixelsToUnits(Gr.Width);
// getting extra item width (border and spacing)
rv.GetItemExtraIntProperty(i, rvepBorderWidth, Integer(BorderWidth));
rv.GetItemExtraIntProperty(i, rvepSpacing, Integer(ImgPadding));
rv.GetItemExtraIntProperty(i, rvepOuterHSpacing, Integer(ImgMargin));
ExtraWidth := (BorderWidth + ImgPadding + ImgMargin) * 2;
ParaStyle := rv.Style.ParaStyles[rv.GetItemPara(i)];
ListItemNo := rv.GetListMarkerInfo(i, ListNo, ListLevel, ListStartFrom, ListReset);
if (ListItemNo >= 0) and (ListNo >= 0) then
begin
// adding indents of list to extra width
inc(ExtraWidth,
rv.Style.ListStyles[ListNo].Levels[ListLevel].LeftIndent +
Max(rv.Style.ListStyles[ListNo].Levels[ListLevel].LeftIndent, 0));
if rv.RVData.GetParaBiDiMode(rv.GetItemPara(ListItemNo)) = rvbdRightToLeft then
inc(ExtraWidth, ParaStyle.LeftIndent)
else
inc(ExtraWidth, ParaStyle.RightIndent);
end
else
begin
// adding indents of paragraph to extra width
inc(ExtraWidth,
ParaStyle.LeftIndent + ParaStyle.RightIndent + Max(ParaStyle.FirstIndent, 0));
end;
// resizing image, if necessary
if ImgWidth + ExtraWidth > MaxWidth then
begin
rv.GetItemExtraIntProperty(i, rvepImageHeight, Integer(ImgHeight));
if ImgHeight <= 0 then
ImgHeight := rv.Style.StandardPixelsToUnits(Gr.Height);
rv.SetItemExtraIntProperty(i, rvepImageWidth, MaxWidth - ExtraWidth);
rv.SetItemExtraIntProperty(i, rvepImageHeight,
MulDiv(ImgHeight, MaxWidth - ExtraWidth, ImgWidth));
end;
end;
end;
Call this code after opening the file and before formatting the document, i.e. just after the case that calls LoadRVF/LoadRTF/LoadDocX.