Componentes.Terceros.DevExp.../official/x.44/ExpressWeb Framework/Sources/cxWebMetrics.pas

408 lines
12 KiB
ObjectPascal

{*******************************************************************}
{ }
{ ExpressWeb Framework by Developer Express }
{ Text Metrics Utils }
{ }
{ Copyright (c) 2000-2009 Developer Express Inc. }
{ ALL RIGHTS RESERVED }
{ }
{ The entire contents of this file is protected by U.S. and }
{ International Copyright Laws. Unauthorized reproduction, }
{ reverse-engineering, and distribution of all or any portion of }
{ the code contained in this file is strictly prohibited and may }
{ result in severe civil and criminal penalties and will be }
{ prosecuted to the maximum extent possible under the law. }
{ }
{ RESTRICTIONS }
{ }
{ THIS SOURCE CODE AND ALL RESULTING INTERMEDIATE FILES }
{ (DCU, OBJ, DLL, ETC.) ARE CONFIDENTIAL AND PROPRIETARY TRADE }
{ SECRETS OF DEVELOPER EXPRESS INC. THE REGISTERED DEVELOPER IS }
{ LICENSED TO DISTRIBUTE THE EXPRESSWEB FRAMEWORK AND ALL }
{ ACCOMPANYING VCL CLASSES AS PART OF AN EXECUTABLE WEB }
{ APPLICATION ONLY. }
{ }
{ THE SOURCE CODE CONTAINED WITHIN THIS FILE AND ALL RELATED }
{ FILES OR ANY PORTION OF ITS CONTENTS SHALL AT NO TIME BE }
{ COPIED, TRANSFERRED, SOLD, DISTRIBUTED, OR OTHERWISE MADE }
{ AVAILABLE TO OTHER INDIVIDUALS WITHOUT EXPRESS WRITTEN CONSENT }
{ AND PERMISSION FROM DEVELOPER EXPRESS INC. }
{ }
{ CONSULT THE END USER LICENSE AGREEMENT FOR INFORMATION ON }
{ ADDITIONAL RESTRICTIONS. }
{ }
{*******************************************************************}
unit cxWebMetrics;
{$I cxVer.inc}
interface
uses
Classes, SysUtils,
{$IFDEF VCL}
Windows, Graphics, Jpeg,
{$ELSE}
Types, Qt, QGraphics,
{$ENDIF}
cxWebUtils, cxWebTypes, cxWebGraphics;
type
TcxWebMetricsUtils = class(TcxAbstractWebMetricsUtils)
private
FPixelsPerInch: Integer;
FCheckWidth, FCheckHeight: Integer;
procedure GetCheckSize;
procedure GetPixelsPerInch;
function GetFontSizeInPoints(AFontSize: TcxWebFontSize): Integer;
function GetTextSize(const AText: string; AWebFont: TcxWebFont): TSize;
protected
function GetCheckWidth: Integer; override;
function GetCheckHeight: Integer; override;
function WebFontToFont(AWebFont: TcxWebFont): {$IFDEF VCL}HFONT{$ELSE}QFontH{$ENDIF};
public
constructor Create;
function CalcEditHeight(AFont: TcxWebFont): Integer; override;
function GetAweCharWidth(AWebFont: TcxWebFont): Integer; override;
function GetTextHeight(const AText: string; AWebFont: TcxWebFont): Integer; override;
function GetTextWidth(const AText: string; AWebFont: TcxWebFont): Integer; override;
end;
TcxWebImageUtils = class(TcxAbstractWebImageUtils)
private
FPicture: TPicture;
FErrMessage: string;
protected
function GetGraphic: TGraphic;
public
constructor Create; override;
destructor Destroy; override;
function GetErrMessage: string; override;
function GetHeight: Integer; override;
function GetWidth: Integer; override;
function IsEmpty: Boolean; override;
procedure SetPath(const APath: string); override;
procedure SetImage(Value: Variant); override;
end;
implementation
uses Variants, cxWebDataUtils, Consts;
{ TcxWebMetricsUtils }
constructor TcxWebMetricsUtils.Create;
begin
inherited;
GetCheckSize;
GetPixelsPerInch;
end;
procedure TcxWebMetricsUtils.GetPixelsPerInch;
{$IFDEF VCL}
var
DC: HDC;
begin
DC := GetDC(0);
FPixelsPerInch := GetDeviceCaps(DC, LOGPIXELSY);
ReleaseDC(0, DC);
{$ELSE}
var
Metrics: QPaintDeviceMetricsH;
begin
Metrics := QPaintDeviceMetrics_create(QWidget_to_QPaintDevice(QApplication_desktop));
FPixelsPerInch := QPaintDeviceMetrics_logicalDpiY(Metrics);
QPaintDeviceMetrics_destroy(Metrics);
{$ENDIF}
end;
function TcxWebMetricsUtils.GetFontSizeInPoints(AFontSize: TcxWebFontSize): Integer;
begin
case AFontSize.Units of
wuPixels:
Result := MulDiv(AFontSize.Value, 72, FPixelsPerInch); // 1 pt = 1/72 in
wuPicas:
Result := MulDiv(AFontSize.Value, 6, FPixelsPerInch); // 1 pc = 12 pt = 1/6 in
wuMillimeters:
Result := MulDiv(AFontSize.Value * 10, 72, 254); // 1 in = 25.4 mm
wuCentimeters:
Result := MulDiv(AFontSize.Value * 100, 72, 254); // 1 in = 2.54 cm
wuInches:
Result := 72 * AFontSize.Value;
// wuEm: TODO: it is equal to the font size of the parent element
// wuEx: TODO: it is equal to the height of the lowercase "x".
// wuPercentage: TODO: it is rate of the font size of the parent element
else {in points}
Result := AFontSize.Value;
end;
end;
function TcxWebMetricsUtils.WebFontToFont(AWebFont: TcxWebFont): {$IFDEF VCL}HFONT{$ELSE}QFontH{$ENDIF};
{$IFDEF VCL}
var
LogFont: TLogFont;
begin
FillChar(LogFont, SizeOf(TLogFont), 0);
with LogFont do
begin
lfHeight := -MulDiv(GetFontSizeInPoints(AWebFont.Size), FPixelsPerInch, 72);
lfWidth := 0;
lfEscapement := 0;
lfOrientation := 0;
if AWebFont.Bold then
lfWeight := FW_BOLD
else
lfWeight := FW_NORMAL;
lfItalic := Byte(AWebFont.Italic);
lfUnderline := Byte(AWebFont.Underline);
lfStrikeOut := Byte(AWebFont.Strikeout);
lfCharSet := DEFAULT_CHARSET;//Byte(Font.Charset);
lfOutPrecision := OUT_DEFAULT_PRECIS;
lfClipPrecision := CLIP_DEFAULT_PRECIS;
lfQuality := DEFAULT_QUALITY;
lfPitchAndFamily := DEFAULT_PITCH;
StrPCopy(lfFaceName, AWebFont.Name);
end;
Result := CreateFontIndirect(LogFont);
{$ELSE}
var
AFontName: WideString;
begin
Result := QFont_Create();
AFontName := AWebFont.Name;
QFont_setFamily(Result, @AFontName);
QFont_setPixelSize(Result, GetFontSizeInPoints(AWebFont.Size));
QFont_setBold(Result, AWebFont.Bold);
QFont_setItalic(Result, AWebFont.Italic);
QFont_setStrikeOut(Result, AWebFont.StrikeOut);
QFont_setUnderline(Result, AWebFont.Underline);
{$ENDIF}
end;
function TcxWebMetricsUtils.GetAweCharWidth(AWebFont: TcxWebFont): Integer;
{$IFDEF VCL}
var
DC: HDC;
PrevFont: HFONT;
TM: TTextMetric;
begin
DC := GetDC(0);
PrevFont := SelectObject(DC, WebFontToFont(AWebFont));
GetTextMetrics(DC, TM);
Result := TM.tmAveCharWidth;
DeleteObject(SelectObject(DC, PrevFont));
ReleaseDC(0, DC);
{$ELSE}
var
AFont: QFontH;
AFontMetrics: QFontMetricsH;
begin
AFont := WebFontToFont(AWebFont);
AFontMetrics := QFontMetrics_Create(AFont);
Result:= QFontMetrics_maxWidth(AFontMetrics);
QFontMetrics_Destroy(AFontMetrics);
QFont_Destroy(AFont);
{$ENDIF}
end;
procedure TcxWebMetricsUtils.GetCheckSize;
{$IFDEF VCL}
const
OBM_CHECKBOXES = 32759;
begin
with TBitmap.Create do
try
Handle := LoadBitmap(0, PChar(OBM_CHECKBOXES));
FCheckWidth := Width div 4;
FCheckHeight := Height div 3;
finally
Free;
end;
{$ELSE}
var
ChSize: TSize;
begin
QStyle_indicatorSize(QApplication_style, @ChSize);
if (ChSize.cx <> 0) and (ChSize.cy <> 0) then
begin
FCheckWidth := ChSize.cx;
FCheckHeight := ChSize.cy;
end
else
begin
FCheckWidth := 13;
FCheckHeight := 13;
end;
{$ENDIF}
end;
function TcxWebMetricsUtils.GetTextSize(const AText: string; AWebFont: TcxWebFont): TSize;
{$IFDEF VCL}
var
DC: HDC;
PrevFont: HFONT;
begin
DC := GetDC(0);
PrevFont := SelectObject(DC, WebFontToFont(AWebFont));
GetTextExtentPoint32(DC, PChar(AText), Length(AText), Result);
DeleteObject(SelectObject(DC, PrevFont));
ReleaseDC(0, DC);
{$ELSE}
var
AFont: QFontH;
AFontMetrics: QFontMetricsH;
AWideText: WideString;
begin
AFont := WebFontToFont(AWebFont);
AFontMetrics := QFontMetrics_Create(AFont);
Result.cy := QFontMetrics_height(AFontMetrics);
AWideText := AText;
Result.cx := QFontMetrics_width(AFontMetrics, @AWideText, Length(AText));
QFontMetrics_Destroy(AFontMetrics);
QFont_Destroy(AFont);
{$ENDIF}
end;
function TcxWebMetricsUtils.GetCheckWidth: Integer;
begin
Result := FCheckWidth;
end;
function TcxWebMetricsUtils.GetCheckHeight: Integer;
begin
Result := FCheckHeight;
end;
function TcxWebMetricsUtils.GetTextHeight(const AText: string; AWebFont: TcxWebFont): Integer;
begin
Result := GetTextSize(AText, AWebFont).cy;
end;
function TcxWebMetricsUtils.GetTextWidth(const AText: string; AWebFont: TcxWebFont): Integer;
begin
Result := GetTextSize(AText, AWebFont).cx;
end;
function TcxWebMetricsUtils.CalcEditHeight(AFont: TcxWebFont): Integer;
{$IFDEF VCL}
var
DC: HDC;
PrevFont: HFont;
Metrics: TTextMetric;
begin
DC := GetDC(0);
PrevFont := SelectObject(DC, WebFontToFont(AFont));
GetTextMetrics(DC, Metrics);
DeleteObject(SelectObject(DC, PrevFont));
ReleaseDC(0, DC);
Result := Metrics.tmHeight + 2 * GetSystemMetrics(SM_CYBORDER);
{$ELSE}
begin
Result := 2 + GetTextHeight('Wq', AFont) + 2;
{$ENDIF}
end;
{ TcxWebImageUtils }
constructor TcxWebImageUtils.Create;
begin
FPicture := TPicture.Create;
FErrMessage := '';
end;
destructor TcxWebImageUtils.Destroy;
begin
FPicture.Free;
inherited;
end;
function TcxWebImageUtils.GetErrMessage: string;
begin
Result := FErrMessage;
end;
function TcxWebImageUtils.GetHeight: Integer;
begin
Result := FPicture.Height;
end;
function TcxWebImageUtils.GetWidth: Integer;
begin
Result := FPicture.Width;
end;
function TcxWebImageUtils.IsEmpty: Boolean;
begin
Result := (FPicture.Graphic = nil) or FPicture.Graphic.Empty;
end;
procedure TcxWebImageUtils.SetPath(const APath: string);
var
Ext: string;
begin
if APath = '' then
begin
FPicture.Graphic := nil;
FErrMessage := '';
end
else
try
Ext := ExtractFileExt(APath);
Delete(Ext, 1, 1);
if Ext = '' then
raise EInvalidGraphic.CreateFmt(SUnknownExtension, [Ext]);
FPicture.LoadFromFile(APath);
FErrMessage := '';
except
on E: Exception do
begin
FPicture.Graphic := nil;
FErrMessage := 'DESIGNER WARNING:' + #13#10 + E.Message + #13#10 + 'Image may be missing or displayed incorrectly.';
end;
end;
end;
procedure TcxWebImageUtils.SetImage(Value: Variant);
var
AStream: TStream;
AHeight, AWidth: Integer;
NewGraphic: TGraphic;
begin
if VarIsType(Value, [varEmpty, VarNull]) then Exit;
{$IFDEF VCL}
NewGraphic := TJPEGImage.Create;
{$ELSE}
NewGraphic := TBitmap.Create;
{$ENDIF}
try
AStream := TMemoryStream.Create;
LoadPicture(AStream, {$IFDEF VCL}nil,{$ENDIF} Value, AHeight, AWidth);
try
AStream.Position := 0;
NewGraphic.LoadFromStream(AStream);
FPicture.Graphic := NewGraphic;
finally
AStream.Free;
end;
finally
NewGraphic.Free;
end;
end;
function TcxWebImageUtils.GetGraphic: TGraphic;
begin
Result := FPicture.Graphic;
end;
initialization
if Assigned(cxWebMetricsUtils) then
cxWebMetricsUtils.Free;
cxWebMetricsUtils := TcxWebMetricsUtils.Create;
cxWebImageUtilsClass := TcxWebImageUtils;
finalization
FreeAndNil(cxWebMetricsUtils);
cxWebImageUtilsClass := nil;
end.