Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2005.11.27;
Скачать: [xml.tar.bz2];

Вниз

EMF - изменение записей - как заполнить intercharacter spacing ?   Найти похожие ветки 

 
GuAV ©   (2005-09-25 01:10) [0]

Здравствуйте.

Пытаюсь изменять emf в EnumMetaFileProc, перезаполняя записи с текстом.
Эти содержат одну или более структуру EMRTEXT (в моём случае EMR_EXTTEXTOUTW содержат одну), после следуют массив символов текста и массив из intercharacter spacing.
Заполняю его приведенной прцедурой. Однако интервалы не выглядят нормально.


procedure SetInterChSpaceW(DC: HDC; Count: Integer; Str: PWCharArray; Arr: PSpacingArray);
var
 OneABC: TABC;
 I: Integer;
begin
 ZeroMemory(Arr, SizeOf(Integer) * Count); // оставлять нули не работает, надо заплонять.
 for I := 0 to Count - 1 do
 begin
   GetCharABCWidthsW(DC, ord(Str[I]), ord(Str[I]), OneABC);
   Arr[I] := OneABC.abcA + Integer(OneABC.abcB) + OneABC.abcC;
 end;
end;


Что я делаю не так ?
Является ли данная идея подстановки строк в EMF неверной в принципе ?


 
GuAV ©   (2005-09-25 01:14) [1]

Забыл указать, DC - это целевой DC - пока paintbox.canvas.handle, count - кол-во символв, str - уже заполненная строка в записи, arr - заполняемый массив в записи.
dword-aling после строки соблюдён.


 
Джо ©   (2005-09-25 04:36) [2]

Может, я не вполне верно понял постановку задачи, но, вообще-то, записи, передаваемые в EnumProc - только для чтения. И если ты что-то в них все-таки поменял, это не значит, что ты изменил что-то в самом метафайле.


 
GuAV ©   (2005-09-25 11:42) [3]

Джо ©   (25.09.05 4:36) [2]

Да, я в курсе. Согласно справке, исходные записи метафайл изменять нельзя вообще. Я вызываю PlayEnhMetaFileRecord из EnumMetaFileProc со старой записью, если менять не нужно, для изменяемой - создаю копию с изменёнными интересующими параметрами и вызываю PlayEnhMetaFileRecord уже с ней.

Приведу наверное весь код - он пока не такй уж большой.

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls, ExtCtrls;

type
 TForm1 = class(TForm)
   Edit1: TEdit;
   Button1: TButton;
   PaintBox1: TPaintBox;
   Memo1: TMemo;
   procedure Button1Click(Sender: TObject);
 private
   { Private declarations }
   FReplList: TStrings;
   procedure OnWideString(var S: WideString);
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

type
 TOnWideString = procedure(var S: WideString) of object;

 TEnumExtraData = class
   FOnWideString: TOnWideString;
 end;

type
 PWCharArray = ^TWCharArray;
 TWCharArray = array[0..0] of Char;
 PSpacingArray = ^TSpacingArray;
 TSpacingArray = array[0..0] of Integer;

procedure SetInterChSpaceW(DC: HDC; Count: Integer; Str: PWCharArray; Arr: PSpacingArray);
var
 OneABC: TABC;
 I: Integer;
begin
 ZeroMemory(Arr, SizeOf(Integer) * Count);
 for I := 0 to Count - 1 do
 begin
   GetCharABCWidthsW(DC, ord(Str[I]), ord(Str[I]), OneABC);
   Arr[I] := OneABC.abcA + Integer(OneABC.abcB) + OneABC.abcC;
 end;
end;

function DAlign(I: DWORD): DWORD;
begin
 Result := (I + 3) and (not 3);
end;

function AllocatePEMRExtTextOutW(Length: Integer): PEMRExtTextOut;
const StructSize = SizeOf(TEMRExtTextOut);
var Size, StrSize: Integer;
begin
 StrSize := DAlign(Length * SizeOf(WideChar));
 Size := StructSize + StrSize + Length * SizeOf(Integer);
 GetMem(Result, Size);
 Result.emr.iType := EMR_EXTTEXTOUTW;
 Result.emr.nSize := Size;
 Result.emrtext.offString := StructSize;
 Result.emrtext.nChars := Length;
 Result.emrtext.offDx := StructSize + StrSize
end;

procedure AssignPEMRExtTextOutOptions(Src, Dest: PEMRExtTextOut);
begin
 Dest.rclBounds := Src.rclBounds;
 Dest.iGraphicsMode := Src.iGraphicsMode;
 Dest.exScale := Src.exScale;
 Dest.eyScale := Src.eyScale;
 Dest.emrtext.ptlReference := Src.emrtext.ptlReference;
 Dest.emrtext.fOptions := Src.emrtext.fOptions;
 Dest.emrtext.rcl := Src.emrtext.rcl;
end;

procedure GetNewPEMRExtTextOutW(DC: HDC; Src: PEMRExtTextOut; var Dest: PEMRExtTextOut;
 Data: TEnumExtraData);
var
 PStr, PArr: Pointer;
 S: WideString;
begin
 PStr := Ptr(Src.emrtext.offString + DWORD(Src));
 SetLength(S, Src.emrtext.nChars);
 Move(PStr^, S[1], Length(S) * SizeOf(WideChar));
 Data.FOnWideString(S);
 Dest := AllocatePEMRExtTextOutW(Length(S));
 AssignPEMRExtTextOutOptions(Src, Dest);
 PStr := Ptr(Dest.emrtext.offString + DWORD(Dest));
 PArr := Ptr(Dest.emrtext.offDx + DWORD(Dest));
 Move(S[1], PStr^, Dest.emrtext.nChars * SizeOf(WideChar));
 SetInterChSpaceW(DC, Dest.emrtext.nChars, PStr, PArr);
end;

function EnumMetaFileProc(hDC: HDC; lpHTable: PHandleTable; lpMFR: PEnhMetaRecord;
 nObj: Integer; lpClientData: LPARAM): Integer; stdcall;
var NewMFR: PEnhMetaRecord;
begin
 case lpMFR.iType of
   EMR_EXTTEXTOUTW:
     begin
       GetNewPEMRExtTextOutW(hDC, PEMRExtTextOut(lpMFR),
         PEMRExtTextOut(NewMFR), TEnumExtraData(lpClientData));
     end;
 else
   NewMFR := nil;
 end;

 if NewMFR <> nil then
 begin
   PlayEnhMetaFileRecord(hDC, lpHTable^, NewMFR^, nObj);
   FreeMem(NewMFR);
 end
 else
 begin
   PlayEnhMetaFileRecord(hDC, lpHTable^, lpMFR^, nObj);
 end;
 Result := 1;
end;

procedure TForm1.Button1Click(Sender: TObject);
var MF: TMetaFile; R: TRect; ED: TEnumExtraData;
begin
 FReplList := TStringList.Create;
 FReplList.AddStrings(Memo1.Lines);
 try
   MF := TMetafile.Create;
   try
     MF.LoadFromFile(Edit1.Text);
     R := Rect(0, 0, MF.Width, MF.Height);
     ED := TEnumExtraData.Create;
     try
       ED.FOnWideString := OnWideString;
       EnumEnhMetaFile(PaintBox1.Canvas.Handle, MF.Handle, @EnumMetaFileProc, ED, R);
     finally
       ED.Free;
     end;
   finally
     MF.Free;
   end;
 finally
   FReplList.Free;
 end;
end;

procedure TForm1.OnWideString(var S: WideString);
begin
 S := FReplList.Values[S];
end;

end.


 
GuAV ©   (2005-09-25 12:24) [4]

@%%@$##$ !


>  TWCharArray = array[0..0] of Char;

TWCharArray = array[0..0] of WideChar; !

Вот тут была ошибка. Не привык с уникодом работать...
Спасибо Джо и всем кто просмотрел и извините за отнятое время..


 
Джо ©   (2005-09-25 16:24) [5]


>  [4] GuAV ©   (25.09.05 12:24)

:)



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2005.11.27;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.47 MB
Время: 0.015 c
14-1130918257
Dmseller
2005-11-02 10:57
2005.11.27
bool.ru - предложение


4-1127744726
XGarik
2005-09-26 18:25
2005.11.27
Убить процесс на КПК


4-1127493249
***_Diman_***
2005-09-23 20:34
2005.11.27
Глюки ListView


3-1129300957
Woolen
2005-10-14 18:42
2005.11.27
"sql state 42000 error code 0" при поиске по GUID через dbExpress


14-1130970062
Kerk
2005-11-03 01:21
2005.11.27
Яндекс :)





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский