Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 25 additions & 18 deletions FastReport.Base/Code/AssemblyDescriptor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
using FastReport.Data;
using FastReport.Engine;
using FastReport.Utils;
#if SKIA
using HMACSHA1 = FastReport.Utils.DetravHMACSHA1;
#endif

namespace FastReport.Code
{
Expand Down Expand Up @@ -324,7 +327,7 @@ public void AddExpressions()
{
// speed up the case: lot of report objects (> 1000) and lot of data columns in the dictionary (> 10000).
Report.Dictionary.CacheAllObjects = true;

InsertItem(Report.CodeHelper.BeginCalcExpression(), "");

ObjectCollection allObjects = Report.AllObjects;
Expand Down Expand Up @@ -374,16 +377,16 @@ public void Compile()
{
if (needCompile)
{
lock(compileLocker)
lock (compileLocker)
{
if (needCompile)
InternalCompile();
}
}
}
}

private void InternalCompile()
{
{
// configure compiler options
CompilerParameters cp = new CompilerParameters();
AddFastReportAssemblies(cp.ReferencedAssemblies); // 2
Expand All @@ -402,22 +405,24 @@ private void InternalCompile()
string errors = string.Empty;
CompilerResults cr;
bool exception = !InternalCompile(cp, out cr);
for (int i = 0; exception && i < RECOMPILE_COUNT ; i++)
for (int i = 0; exception && i < RECOMPILE_COUNT; i++)
{
exception = !HandleCompileErrors(cp, cr, out errors);
}

if (exception && errors != string.Empty)
throw new CompilerException(errors);
}

private string GetAssemblyHash(CompilerParameters cp)
{
StringBuilder assemblyHashSB = new StringBuilder();
foreach (string a in cp.ReferencedAssemblies)
assemblyHashSB.Append(a);
assemblyHashSB.Append(scriptText.ToString());
byte[] hash = null;
var script = scriptText.ToString();
assemblyHashSB.Append(script);
byte[] hash;

using (HMACSHA1 hMACSHA1 = new HMACSHA1(Encoding.ASCII.GetBytes(shaKey)))
{
hash = hMACSHA1.ComputeHash(Encoding.Unicode.GetBytes(assemblyHashSB.ToString()));
Expand All @@ -434,11 +439,12 @@ private bool InternalCompile(CompilerParameters cp, out CompilerResults cr)

// find assembly in cache
string assemblyHash = GetAssemblyHash(cp);
Assembly cachedAssembly = null;
Assembly cachedAssembly;
if (FAssemblyCache.TryGetValue(assemblyHash, out cachedAssembly))
{
Assembly = cachedAssembly;
InitInstance(Assembly.CreateInstance("FastReport.ReportScript"));
var reportScript = Assembly.CreateInstance("FastReport.ReportScript");
InitInstance(reportScript);
cr = null;
return true;
}
Expand All @@ -465,7 +471,8 @@ private bool InternalCompile(CompilerParameters cp, out CompilerResults cr)
FAssemblyCache.TryAdd(assemblyHash, cr.CompiledAssembly);

Assembly = cr.CompiledAssembly;
InitInstance(Assembly.CreateInstance("FastReport.ReportScript"));
var reportScript = Assembly.CreateInstance("FastReport.ReportScript");
InitInstance(reportScript);
return true;
}
}
Expand Down Expand Up @@ -509,10 +516,10 @@ private bool HandleCompileErrors(CompilerParameters cp, CompilerResults cr, out
errors = string.Empty;
List<string> additionalAssemblies = new List<string>(4);
Regex regex;

if (Config.WebMode && Config.EnableScriptSecurity)
{
for (int i=0; i < cr.Errors.Count; )
for (int i = 0; i < cr.Errors.Count;)
{
CompilerError ce = cr.Errors[i];
if (ce.ErrorNumber == "CS1685") // duplicate class
Expand All @@ -534,22 +541,22 @@ private bool HandleCompileErrors(CompilerParameters cp, CompilerResults cr, out
message = message.Replace("{typeName}", typeName); //$"Please don't use the type {typeName}";

ce.ErrorText = message;

}
else if (ce.ErrorNumber == "CS0117") // user using a forbidden method
{
const string pattern = "[\"'](\\S+)[\"']";
regex = new Regex(pattern, RegexOptions.Compiled);
MatchCollection mathes = regex.Matches(ce.ErrorText);
if(mathes.Count > 1)
if (mathes.Count > 1)
{
string methodName = mathes[1].Value;

const string res = "Web,ScriptSecurity,ForbiddenMethod";
string message = Res.TryGet(res);
if (string.Equals(res, message))
message = "Please don't use the method " + methodName;
else
else
message = message.Replace("{methodName}", methodName); //$"Please don't use the method {methodName}";

ce.ErrorText = message;
Expand Down Expand Up @@ -586,7 +593,7 @@ private bool HandleCompileErrors(CompilerParameters cp, CompilerResults cr, out
int line = GetScriptLine(ce.Line);
// error is inside own items
if (line == -1)
{
{
string errObjName = GetErrorObjectName(ce.Line);

if (Config.CompilerSettings.ExceptionBehaviour != CompilerExceptionBehaviour.Default)
Expand Down Expand Up @@ -624,7 +631,7 @@ private bool HandleCompileErrors(CompilerParameters cp, CompilerResults cr, out
}
}

if(additionalAssemblies.Count > 0) // need recompile
if (additionalAssemblies.Count > 0) // need recompile
return ReCompile(cp, cr, additionalAssemblies);

return false;
Expand Down
25 changes: 24 additions & 1 deletion FastReport.Base/Export/ExportUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,19 @@ internal static bool ParseTextToPercent(string text, FormatBase format, out deci
return false;
}

internal static string GetExcelFormatSpecifier(FormatBase format)
internal static string GetExcelFormatSpecifier(FormatBase format, bool useLocale = false)
{
if (format is CurrencyFormat)
{
NumberFormatInfo f = (format as CurrencyFormat).GetNumberFormatInfo();

if (useLocale)
{
(format as CurrencyFormat).UseLocale = true;
f = (format as CurrencyFormat).GetNumberFormatInfo();
f.CurrencyDecimalDigits = CultureInfo.CurrentCulture.NumberFormat.CurrencyDecimalDigits;
}

string fm_str = "#,##0";
if (f.CurrencyDecimalDigits > 0)
{
Expand Down Expand Up @@ -148,6 +156,14 @@ internal static string GetExcelFormatSpecifier(FormatBase format)
else if (format is NumberFormat)
{
NumberFormatInfo f = (format as NumberFormat).GetNumberFormatInfo();

if (useLocale)
{
(format as NumberFormat).UseLocale = true;
f = (format as NumberFormat).GetNumberFormatInfo();
f.CurrencyDecimalDigits = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalDigits;
}

string fm_str = "#,##0";
if (f.NumberDecimalDigits > 0)
{
Expand Down Expand Up @@ -186,6 +202,13 @@ internal static string GetExcelFormatSpecifier(FormatBase format)
else if (format is PercentFormat)
{
string pattern = "0";

if (useLocale)
{
(format as PercentFormat).UseLocale = true;
(format as PercentFormat).DecimalDigits = CultureInfo.CurrentCulture.NumberFormat.PercentDecimalDigits;
}

if ((format as PercentFormat).DecimalDigits > 0)
{
pattern += ".";
Expand Down
23 changes: 12 additions & 11 deletions FastReport.Base/Export/Html/HTMLExportLayers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -568,19 +568,20 @@ private string GetLayerPicture(ReportComponentBase obj, out float Width, out flo
obj.Draw(new FRPaintEventArgs(g, Zoom + zoom - 1, Zoom + zoom - 1, Report.GraphicCache));
obj.Border.Lines = oldLines;
}
using (Bitmap b = new Bitmap((int)Width, (int)Height))
{
using (Graphics gr = Graphics.FromImage(b))
if(Width > 0 && Height > 0)
using (Bitmap b = new Bitmap((int)Width, (int)Height))
{
gr.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
gr.DrawImage(image, 0, 0, (int)Width, (int)Height);
}
using (Graphics gr = Graphics.FromImage(b))
{
gr.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
gr.DrawImage(image, 0, 0, (int)Width, (int)Height);
}

if (FPictureFormat == System.Drawing.Imaging.ImageFormat.Jpeg)
ExportUtils.SaveJpeg(b, PictureStream, 95);
else
b.Save(PictureStream, FPictureFormat);
}
if (FPictureFormat == System.Drawing.Imaging.ImageFormat.Jpeg)
ExportUtils.SaveJpeg(b, PictureStream, 95);
else
b.Save(PictureStream, FPictureFormat);
}
}
PictureStream.Position = 0;

Expand Down
5 changes: 5 additions & 0 deletions FastReport.Base/Preview/SourcePages.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,11 @@ public void Add(ReportPage page)
pages.Add(CloneObjects(page, null) as ReportPage);
}

public void RemoveLast()
{
pages.RemoveAt(pages.Count - 1);
}

public void Clear()
{
while (pages.Count > 0)
Expand Down
2 changes: 1 addition & 1 deletion FastReport.Base/Report.cs
Original file line number Diff line number Diff line change
Expand Up @@ -879,7 +879,7 @@ public IGraphics MeasureGraphics
measureBitmap = new Bitmap(1, 1);
measureGraphics = new GdiGraphics(measureBitmap);
#else
measureGraphics = new GdiGraphics(Graphics.FromHwnd(IntPtr.Zero), false);
measureGraphics = GdiGraphics.FromGraphics(Graphics.FromHwnd(IntPtr.Zero));
#endif
}
return measureGraphics;
Expand Down
41 changes: 35 additions & 6 deletions FastReport.Base/TextObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -287,11 +287,11 @@ public partial class TextObject : TextObjectBase
private FormatBase savedFormat;
private InlineImageCache inlineImageCache;
private ParagraphFormat paragraphFormat;
private bool preserveLastLineSpace;
#endregion

#region Properties


/// <summary>
/// Gets or sets a paragraph format for a new html rendering type, not for others rendering
/// </summary>
Expand Down Expand Up @@ -697,6 +697,8 @@ internal bool IsAdvancedRendererNeeded
get { return HorzAlign == HorzAlign.Justify || Wysiwyg || LineHeight != 0 || HasHtmlTags; }
}

internal bool PreserveLastLineSpace { get { return preserveLastLineSpace; } set { preserveLastLineSpace = value; } }

/// <summary>
/// Cache for inline images
/// </summary>
Expand Down Expand Up @@ -1118,14 +1120,40 @@ internal HtmlTextRenderer GetHtmlTextRenderer(IGraphics g, float scale, float fo
return GetHtmlTextRenderer(Text, g, fontScale, scale, fontScale, textRect, format, false);
}

internal HtmlTextRenderer GetHtmlTextRenderer(string text, IGraphics g, float formatScale, float scale, float fontScale, RectangleF textRect, StringFormat format, bool isPrinting)
{
internal HtmlTextRenderer GetHtmlTextRenderer(string text, IGraphics g, float formatScale, float scale, float fontScale,
RectangleF textRect, StringFormat format, bool isPrinting)
{
#if true
HtmlTextRenderer.RendererContext context;
context.text = text;
context.g = g;
context.font = font.FontFamily;
context.size = font.Size;
context.style = font.Style; // no keep
context.color = TextColor; // no keep
context.underlineColor = textOutline.Color;
context.rect = textRect;
context.underlines = Underlines;
context.format = format; // no keep
context.horzAlign = horzAlign;
context.vertAlign = vertAlign;
context.paragraphFormat = ParagraphFormat.MultipleScale(formatScale);
context.forceJustify = ForceJustify;
context.scale = scale* 96f / DrawUtils.ScreenDpi;
context.fontScale = fontScale * 96f / DrawUtils.ScreenDpi;
context.cache = InlineImageCache;
context.isPrinting = isPrinting;
context.isDifferentTabPositions = TabPositions.Count > 0;
context.keepLastLineSpace = this.PreserveLastLineSpace;
return new HtmlTextRenderer(context);
#else
bool isDifferentTabPositions = TabPositions.Count > 0;
return new HtmlTextRenderer(text, g, font.FontFamily, font.Size, font.Style, TextColor,
textOutline.Color, textRect, Underlines,
format, horzAlign, vertAlign, ParagraphFormat.MultipleScale(formatScale), ForceJustify,
scale * 96f / DrawUtils.ScreenDpi, fontScale * 96f / DrawUtils.ScreenDpi, InlineImageCache,
isPrinting, isDifferentTabPositions);
#endif
}

/// <summary>
Expand Down Expand Up @@ -1474,9 +1502,9 @@ internal void ApplyCondition(HighlightCondition c)
Visible = c.Visible;
}

#endregion
#endregion

#region Report Engine
#region Report Engine
/// <inheritdoc/>
public override string[] GetExpressions()
{
Expand Down Expand Up @@ -1705,7 +1733,7 @@ internal IEnumerable<PictureObject> GetPictureFromHtmlText(AdvancedTextRenderer
}
}
}
#endregion
#endregion

/// <summary>
/// Initializes a new instance of the <see cref="TextObject"/> class with default settings.
Expand All @@ -1725,6 +1753,7 @@ public TextObject()
highlight = new ConditionCollection();
FlagSerializeStyle = false;
SetFlags(Flags.HasSmartTag, true);
preserveLastLineSpace = false;
}
}
}
2 changes: 2 additions & 0 deletions FastReport.Base/Utils/Config.cs
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,7 @@ private static void CurrentDomain_ProcessExit(object sender, EventArgs e)
SaveUIOptions();
SavePreviewSettings();
SaveCompilerSettings();
SaveAuthServiceUser();
#if !COMMUNITY
SaveExportOptions();
#endif
Expand Down Expand Up @@ -492,6 +493,7 @@ private static void LoadConfig()
RestoreDefaultLanguage();
RestoreUIOptions();
RestorePreviewSettings();
RestoreAuthServiceUser();
RestoreCompilerSettings();
Res.LoadDefaultLocale();
AppDomain.CurrentDomain.ProcessExit += new EventHandler(CurrentDomain_ProcessExit);
Expand Down
8 changes: 4 additions & 4 deletions FastReport.Base/Utils/Crypter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -236,11 +236,11 @@ public class Murmur3
/// </summary>
[CLSCompliantAttribute(false)]
public static ulong READ_SIZE = 16;
private static ulong C1 = 0x87c37b91114253d5L;
private static ulong C2 = 0x4cf5ad432745937fL;
private const ulong C1 = 0x87c37b91114253d5L;
private const ulong C2 = 0x4cf5ad432745937fL;

private ulong length;
private uint seed = 0; // if want to start with a seed, create a constructor
private readonly uint seed = 0; // if want to start with a seed, create a constructor
ulong h1;
ulong h2;

Expand Down Expand Up @@ -311,7 +311,7 @@ private void ProcessBytes(byte[] bb)
h1 = seed;
this.length = 0L;
int pos = 0;
int npos = 0;
int npos;
ulong remaining = (ulong)bb.Length;
// read 128 bits, 16 bytes, 2 longs in eacy cycle
while (remaining >= READ_SIZE) unchecked
Expand Down
2 changes: 1 addition & 1 deletion FastReport.Base/Utils/FRPaintEventArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public FRPaintEventArgs(IGraphics g, float scaleX, float scaleY, GraphicCache ca
/// <param name="scaleY">Y scale factor.</param>
/// <param name="cache">Cache that contains graphics objects.</param>
public FRPaintEventArgs(Graphics g, float scaleX, float scaleY, GraphicCache cache) :
this(new GdiGraphics(g, false), scaleX, scaleY, cache)
this(GdiGraphics.FromGraphics(g), scaleX, scaleY, cache)
{
}
}
Expand Down
Loading