// // PDFsharp - A library for processing PDF // // Authors: // Klaus Potzesny // // Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany) // // http://www.pdfsharp.com // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. using System; namespace PdfSharp.Drawing.BarCodes { /// /// Internal base class for several bar code types. /// public abstract class ThickThinBarCode : BarCode // TODO: The name is not optimal { /// /// Initializes a new instance of the class. /// public ThickThinBarCode(string code, XSize size, CodeDirection direction) : base(code, size, direction) { } internal override void InitRendering(BarCodeRenderInfo info) { base.InitRendering(info); CalcThinBarWidth(info); info.BarHeight = Size.Height; // HACK in ThickThinBarCode if (TextLocation != TextLocation.None) info.BarHeight *= 4.0 / 5; #if DEBUG_ XColor back = XColors.LightSalmon; back.A = 0.3; XSolidBrush brush = new XSolidBrush(back); info.Gfx.DrawRectangle(brush, new XRect(info.Center - size / 2, size)); #endif switch (Direction) { case CodeDirection.RightToLeft: info.Gfx.RotateAtTransform(180, info.Position); break; case CodeDirection.TopToBottom: info.Gfx.RotateAtTransform(90, info.Position); break; case CodeDirection.BottomToTop: info.Gfx.RotateAtTransform(-90, info.Position); break; } } /// /// Gets or sets the ration between thick an thin lines. Must be between 2 and 3. /// Optimal and also default value is 2.6. /// public override double WideNarrowRatio { get { return _wideNarrowRatio; } set { if (value > 3 || value < 2) throw new ArgumentOutOfRangeException("value", BcgSR.Invalid2of5Relation); _wideNarrowRatio = value; } } double _wideNarrowRatio = 2.6; /// /// Renders a thick or thin line for the bar code. /// /// /// Determines whether a thick or a thin line is about to be rendered. internal void RenderBar(BarCodeRenderInfo info, bool isThick) { double barWidth = GetBarWidth(info, isThick); double height = Size.Height; double xPos = info.CurrPos.X; double yPos = info.CurrPos.Y; switch (TextLocation) { case TextLocation.AboveEmbedded: height -= info.Gfx.MeasureString(Text, info.Font).Height; yPos += info.Gfx.MeasureString(Text, info.Font).Height; break; case TextLocation.BelowEmbedded: height -= info.Gfx.MeasureString(Text, info.Font).Height; break; } XRect rect = new XRect(xPos, yPos, barWidth, height); info.Gfx.DrawRectangle(info.Brush, rect); info.CurrPos.X += barWidth; } /// /// Renders a thick or thin gap for the bar code. /// /// /// Determines whether a thick or a thin gap is about to be rendered. internal void RenderGap(BarCodeRenderInfo info, bool isThick) { info.CurrPos.X += GetBarWidth(info, isThick); } /// /// Renders a thick bar before or behind the code. /// internal void RenderTurboBit(BarCodeRenderInfo info, bool startBit) { if (startBit) info.CurrPos.X -= 0.5 + GetBarWidth(info, true); else info.CurrPos.X += 0.5; //GetBarWidth(info, true); RenderBar(info, true); if (startBit) info.CurrPos.X += 0.5; //GetBarWidth(info, true); } internal void RenderText(BarCodeRenderInfo info) { if (info.Font == null) info.Font = new XFont("Courier New", Size.Height / 6); XPoint center = info.Position + CalcDistance(Anchor, AnchorType.TopLeft, Size); switch (TextLocation) { case TextLocation.Above: center = new XPoint(center.X, center.Y - info.Gfx.MeasureString(Text, info.Font).Height); info.Gfx.DrawString(Text, info.Font, info.Brush, new XRect(center, Size), XStringFormats.TopCenter); break; case TextLocation.AboveEmbedded: info.Gfx.DrawString(Text, info.Font, info.Brush, new XRect(center, Size), XStringFormats.TopCenter); break; case TextLocation.Below: center = new XPoint(center.X, info.Gfx.MeasureString(Text, info.Font).Height + center.Y); info.Gfx.DrawString(Text, info.Font, info.Brush, new XRect(center, Size), XStringFormats.BottomCenter); break; case TextLocation.BelowEmbedded: info.Gfx.DrawString(Text, info.Font, info.Brush, new XRect(center, Size), XStringFormats.BottomCenter); break; } } /// /// Gets the width of a thick or a thin line (or gap). CalcLineWidth must have been called before. /// /// /// Determines whether a thick line's with shall be returned. internal double GetBarWidth(BarCodeRenderInfo info, bool isThick) { if (isThick) return info.ThinBarWidth * _wideNarrowRatio; return info.ThinBarWidth; } internal abstract void CalcThinBarWidth(BarCodeRenderInfo info); } }