/// <summary>Append a line segment to the current figure.</summary> /// <param name="point">The end point coordinates.<see cref="System.PointD"/></param> public void AddLine(System.Windows.Point point) { if (_elements.Count == 0) { SimpleLog.LogLine(TraceEventType.Error, CLASS_NAME + "::AddLine() Adding a line to without any previous element is not supported!"); return; } X11LineToPathSegment lt = new X11LineToPathSegment(point); _elements.Add(lt); }
/// <summary>Get the 'ready to use' pixmap (color depth) for tile brush, with transform applied.</summary> /// <param name="x11display"> The display pointer, that specifies the connection to the X server. <see cref="System.IntPtr"/> </param> /// <param name="X11drawableSrc">The drawable that indicates the screen.<see cref="IntPtr"/></param> /// <returns>The 'ready to use' bitmap (1 bit depth) for hatch brush.<see cref="IntPtr"/></returns> internal IntPtr TilePixmap(IntPtr x11display, IntPtr X11drawableSrc) { if (_brushType != X11BrushInfo.BrushType.Image) { return(IntPtr.Zero); } if (_currentTilePixmap != IntPtr.Zero && _currentTilePixmapInvalid == false) { return(_currentTilePixmap); } foreach (TransformedPixmap stockPixmap in _tileStockPixmaps) { if (_tilePixmapRotation >= stockPixmap.RatationAngle - TRANSFORM_FUZZY && _tilePixmapRotation <= stockPixmap.RatationAngle + TRANSFORM_FUZZY && /*_tileZoom*/ 1.0 >= stockPixmap.Zoom - TRANSFORM_FUZZY && /*_tileZoom*/ 1.0 <= stockPixmap.Zoom + TRANSFORM_FUZZY) { _currentTilePixmap = stockPixmap.Pixmap; _currentTilePixmapInvalid = false; return(_currentTilePixmap); } } if (x11display != IntPtr.Zero && X11drawableSrc != IntPtr.Zero) { if (_tilePixmapRotation >= -TRANSFORM_FUZZY && _tilePixmapRotation <= TRANSFORM_FUZZY) { _currentTilePixmap = _tileGraphic.CreateIndependentGraphicPixmap(x11display, X11drawableSrc); } else { _currentTilePixmap = _tileGraphic.CreateIndependentGraphicPixmapRotated(x11display, X11drawableSrc, _tilePixmapRotation); } _tilePixmapDisplay = x11display; _tileStockPixmaps.Add(new TransformedPixmap(_currentTilePixmap, _tilePixmapRotation, 1.0)); _currentTilePixmapInvalid = false; return(_currentTilePixmap); } SimpleLog.LogLine(TraceEventType.Error, CLASS_NAME + "::TilePixmap () Neither display nor drawable can be IntPtr.Zero."); return(IntPtr.Zero); }
// ############################################################################### // ### M E T H O D S // ############################################################################### #region Methods /// <summary>Get the 'ready to use' bitmap (1 bit depth) for hatch brush.</summary> /// <param name="x11display"> The display pointer, that specifies the connection to the X server. <see cref="System.IntPtr"/> </param> /// <param name="X11drawableSrc">The drawable that indicates the screen.<see cref="IntPtr"/></param> /// <returns>The 'ready to use' bitmap (1 bit depth) for hatch brush.<see cref="IntPtr"/></returns> internal IntPtr HatchBitmap(IntPtr x11display, IntPtr X11drawableSrc) { if (_brushType != X11BrushInfo.BrushType.Hatch) { return(IntPtr.Zero); } if (_hatchBitmap != IntPtr.Zero) { return(_hatchBitmap); } if (x11display != IntPtr.Zero && X11drawableSrc != IntPtr.Zero) { PixmapInfo hatch = this.Hatch; _hatchBitmap = X11.X11lib.XCreateBitmapFromData(x11display, X11drawableSrc, hatch.Bits, hatch.Width, hatch.Height); _hatchDisplay = x11display; return(_hatchBitmap); } SimpleLog.LogLine(TraceEventType.Error, CLASS_NAME + "::HatchBitmap () Neither display nor drawable can be IntPtr.Zero."); return(IntPtr.Zero); }
// ############################################################################### // ### M E T H O D S // ############################################################################### #region Methods /// <summary>Prepare a font or fonteset for utilization with Xrw.</summary> /// <param name="fontSpecification">The font specification, that identifies a font/fontset.<see cref="System.String"/></param> /// <param name="x11display">The display pointer, that specifies the connection to the X server.<see cref="IntPtr"/></param> /// <param name="useFontset">The flag defining whether to use a fontset or a single font.<see cref="System.Boolean"/></param> /// <param name="fontData">The resulting font data on success, or null otherwise.<see cref="X11.X11FontData"/></param> /// <returns>True on success, or false otherwise.<see cref="System.Boolean"/></returns> public static bool PrepareFont(string fontSpecification, IntPtr x11display, bool useFontset, ref X11.X11FontData fontData) { fontData = null; foreach (KeyValuePair <FontDataKey, X11FontData> loadedFont in _loadedFonts) { if (loadedFont.Key.FontSpecification == fontSpecification && loadedFont.Key.X11Display == x11display && loadedFont.Key.UseFontset) { fontData = loadedFont.Value; return(true); } } FontDataKey key = new FontDataKey(fontSpecification, x11display, useFontset); if (useFontset) { IntPtr missingCharsetList; TInt missingCharsetCount; X11.XID fontsetResourceId = X11lib.XCreateFontSet(x11display, fontSpecification, out missingCharsetList, out missingCharsetCount, IntPtr.Zero); // Check whether directly matching fontset has been loaded, and - if not - load the most similar fontset (fuzzy). int fuzzyFactor = 0; string fuzzyFontSpecification = (fontsetResourceId == (X11.XID) 0 ? fontSpecification : null); while (fontsetResourceId == (X11.XID) 0 && fuzzyFactor < 3) { string lastFuzzyFontSpecification = fuzzyFontSpecification; if (fuzzyFactor == 0) { fuzzyFontSpecification = X11FontData.ModifyFontSpecificationStretch(fuzzyFontSpecification, "*"); } if (fuzzyFactor == 1) { fuzzyFontSpecification = X11FontData.ModifyFontSpecificationWieght(fuzzyFontSpecification, "*"); } if (fuzzyFactor == 2) { fuzzyFontSpecification = X11FontData.ModifyFontSpecificationSlant(fuzzyFontSpecification, "*"); } fuzzyFactor++; // Safe time if no change has been made. if (lastFuzzyFontSpecification == fuzzyFontSpecification) { continue; } if (!string.IsNullOrEmpty(lastFuzzyFontSpecification) && lastFuzzyFontSpecification.Trim() != "") { fontsetResourceId = X11lib.XCreateFontSet(x11display, fuzzyFontSpecification, out missingCharsetList, out missingCharsetCount, IntPtr.Zero); if (fontsetResourceId != (X11.XID) 0) { SimpleLog.LogLine(TraceEventType.Information, CLASS_NAME + "::PrepareFont () Fuzzy load fontset with specification '" + fuzzyFontSpecification + "' " + "instead of '" + fontSpecification + "' succeeded."); } } } // Check whether directly matching or most similar fontset has been loaded, and - if not - load a fallback fontset. string extFontSpecification = null; if (fontsetResourceId == (X11.XID) 0) { // Let the font server guess a fallback fontset. if (!string.IsNullOrEmpty(fontSpecification) && fontSpecification.Trim() != "" && !fontSpecification.Trim().EndsWith(",*")) { extFontSpecification = fontSpecification + ",*"; SimpleLog.LogLine(TraceEventType.Warning, CLASS_NAME + "::PrepareFont () Can not load a fontset with specification '" + fontSpecification + "'."); SimpleLog.LogLine(TraceEventType.Information, CLASS_NAME + "::PrepareFont () Retry to load a fontset with specification '" + extFontSpecification + "'."); fontsetResourceId = X11lib.XCreateFontSet(x11display, extFontSpecification, out missingCharsetList, out missingCharsetCount, IntPtr.Zero); } // The font specification already includs a joker to guess a fallback fontset. else { SimpleLog.LogLine(TraceEventType.Error, CLASS_NAME + "::PrepareFont () Can not load a fontset with specification '" + fontSpecification + "'."); // No success at all - even with a guess of a fallback fontset! return(false); } } // Check whether matching fontset has been loaded. if (fontsetResourceId == (X11.XID) 0) { SimpleLog.LogLine(TraceEventType.Error, CLASS_NAME + "::PrepareFont () Can not load a fontset with specification '" + extFontSpecification + "'."); // No success at all - even with a guess of a fallback fontset! return(false); } if (!string.IsNullOrEmpty(extFontSpecification)) { SimpleLog.LogLine(TraceEventType.Information, CLASS_NAME + "::PrepareFont () Successfully loaded best matching fontset for specification '" + fontSpecification + "' " + "using specification '" + extFontSpecification + "'."); } else if (!string.IsNullOrEmpty(fuzzyFontSpecification)) { SimpleLog.LogLine(TraceEventType.Information, CLASS_NAME + "::PrepareFont () Successfully loaded best matching fontset for specification '" + fontSpecification + "' " + "using specification '" + fuzzyFontSpecification + "'."); } else { SimpleLog.LogLine(TraceEventType.Information, CLASS_NAME + "::PrepareFont () Successfully loaded best matching fontset for specification '" + fontSpecification + "'."); } for (int countCharSet = 0; countCharSet < (int)missingCharsetCount; countCharSet++) { IntPtr p = Marshal.ReadIntPtr(missingCharsetList, countCharSet * Marshal.SizeOf(typeof(IntPtr))); string s = Marshal.PtrToStringAuto(p); if (!string.IsNullOrEmpty(extFontSpecification)) { SimpleLog.LogLine(TraceEventType.Warning, CLASS_NAME + "::PrepareFont () Fontset for specification '" + extFontSpecification + "' is missing font for charset '" + s + "'."); } else if (!string.IsNullOrEmpty(fuzzyFontSpecification)) { SimpleLog.LogLine(TraceEventType.Warning, CLASS_NAME + "::PrepareFont () Fontset for specification '" + fuzzyFontSpecification + "' is missing font for charset '" + s + "'."); } else { SimpleLog.LogLine(TraceEventType.Warning, CLASS_NAME + "::PrepareFont () Fontset for specification '" + fontSpecification + "' is missing font for charset '" + s + "'."); } } // Calculate maximum font height, ascent and descent. int ascent = 0; int descent = 0; X11lib.XFontSetExtents extents = X11lib.XExtentsOfFontSet(fontsetResourceId); X11lib.XFontStruct[] fontStructArray; string[] fontNameArray; int maxFonts; maxFonts = X11lib.XFontsOfFontSet(fontsetResourceId, out fontStructArray, out fontNameArray); for (int countFonts = 0; countFonts < maxFonts; countFonts++) { if (ascent < (int)fontStructArray[countFonts].ascent) { ascent = (int)fontStructArray[countFonts].ascent; } if (descent < (int)fontStructArray[countFonts].descent) { descent = (int)fontStructArray[countFonts].descent; } } string finalFontSpecification = null; if (!string.IsNullOrEmpty(extFontSpecification)) { finalFontSpecification = extFontSpecification; } else if (!string.IsNullOrEmpty(fuzzyFontSpecification)) { finalFontSpecification = fuzzyFontSpecification; } else { finalFontSpecification = fontSpecification; } // Maximum font height, ascent and descent might be frequently used for calculation. fontData = X11FontData.NewFontSetData(finalFontSpecification, x11display, fontsetResourceId, (int)extents.max_logical_extent.height, ascent, descent); IntPtr gc = X11lib.XCreateGC(x11display, X11lib.XDefaultRootWindow(x11display), 0, IntPtr.Zero); if (gc != IntPtr.Zero) { fontData.SetTypicalCharWidth(AverageCharacterWidth(x11display, gc, fontData)); X11lib.XFreeGC(x11display, gc); } _loadedFonts.Add(key, fontData); return(true); } // Use font, if fontset isn't supported. else // of (useFontset) { // Load font and query font structure (to get maximum font height, ascent and descent). IntPtr fontStructure = X11lib.XLoadQueryFont(x11display, fontSpecification); // Check whether directly matching font has been loaded, and - if not - load the most similar font (fuzzy). int fuzzyFactor = 0; string fuzzyFontSpecification = (fontStructure == IntPtr.Zero ? fontSpecification : null); while (fontStructure == IntPtr.Zero && fuzzyFactor < 3) { string lastFuzzyFontSpecification = fuzzyFontSpecification; if (fuzzyFactor == 0) { fuzzyFontSpecification = X11FontData.ModifyFontSpecificationStretch(fuzzyFontSpecification, "*"); } if (fuzzyFactor == 1) { fuzzyFontSpecification = X11FontData.ModifyFontSpecificationWieght(fuzzyFontSpecification, "*"); } if (fuzzyFactor == 2) { fuzzyFontSpecification = X11FontData.ModifyFontSpecificationSlant(fuzzyFontSpecification, "*"); } fuzzyFactor++; // Safe time if no change has been made. if (lastFuzzyFontSpecification == fuzzyFontSpecification) { continue; } if (!string.IsNullOrEmpty(lastFuzzyFontSpecification) && lastFuzzyFontSpecification.Trim() != "") { fontStructure = X11lib.XLoadQueryFont(x11display, lastFuzzyFontSpecification); if (fontStructure != IntPtr.Zero) { SimpleLog.LogLine(TraceEventType.Information, CLASS_NAME + "::PrepareFont () Fuzzy load font with specification '" + fuzzyFontSpecification + "' " + "instead of '" + fontSpecification + "' succeeded."); } } } // Check whether directly matching or most similar font has been loaded, and - if not - load a fallback font. string extFontSpecification = null; if (fontStructure != IntPtr.Zero) { // Let the font server guess a fallback fontset. if (!string.IsNullOrEmpty(fontSpecification) && fontSpecification.Trim() != "" && !fontSpecification.Trim().EndsWith(",*")) { extFontSpecification = fontSpecification + ",*"; SimpleLog.LogLine(TraceEventType.Warning, CLASS_NAME + "::PrepareFont () Can not load a fontset with specification '" + fontSpecification + "'."); SimpleLog.LogLine(TraceEventType.Information, CLASS_NAME + "::PrepareFont () Retry to load a fontset with specification '" + extFontSpecification + "'."); fontStructure = X11lib.XLoadQueryFont(x11display, extFontSpecification); } // The font specification already includs a joker to guess a fallback fontset. else { SimpleLog.LogLine(TraceEventType.Error, CLASS_NAME + "::PrepareFont () Can not load a font with specification '" + fontSpecification + "'."); // No success at all - even with a guess of a fallback font! return(false); } } // Check whether matching font has been loaded. if (fontStructure == IntPtr.Zero) { SimpleLog.LogLine(TraceEventType.Error, CLASS_NAME + "::PrepareFont () Can not load a font with specification '" + fontSpecification + "'."); // No success at all - even with a guess of a fallback font! return(false); } if (!string.IsNullOrEmpty(extFontSpecification)) { SimpleLog.LogLine(TraceEventType.Information, CLASS_NAME + "::PrepareFont () Successfully loaded best matching font for specification '" + fontSpecification + "' " + "using specification '" + extFontSpecification + "'."); } else if (!string.IsNullOrEmpty(fuzzyFontSpecification)) { SimpleLog.LogLine(TraceEventType.Information, CLASS_NAME + "::PrepareFont () Successfully loaded best matching font for specification '" + fontSpecification + "' " + "using specification '" + fuzzyFontSpecification + "'."); } else { SimpleLog.LogLine(TraceEventType.Information, CLASS_NAME + "::PrepareFont () Successfully loaded best matching font for specification '" + fontSpecification + "'."); } X11lib.XFontStruct fs = (X11lib.XFontStruct)Marshal.PtrToStructure(fontStructure, typeof(X11lib.XFontStruct)); string finalFontSpecification = null; if (!string.IsNullOrEmpty(extFontSpecification)) { finalFontSpecification = extFontSpecification; } else if (!string.IsNullOrEmpty(fuzzyFontSpecification)) { finalFontSpecification = fuzzyFontSpecification; } else { finalFontSpecification = fontSpecification; } // Maximum font height, ascent and descent might be frequently used for calculation. fontData = X11FontData.NewSingleFontData(finalFontSpecification, x11display, fs.fid, (int)fs.ascent + (int)fs.descent, (int)fs.ascent, (int)fs.descent); IntPtr gc = X11lib.XCreateGC(x11display, X11lib.XDefaultRootWindow(x11display), 0, IntPtr.Zero); if (gc != IntPtr.Zero) { fontData.SetTypicalCharWidth(AverageCharacterWidth(x11display, gc, fontData)); X11lib.XFreeGC(x11display, gc); } _loadedFonts.Add(key, fontData); return(true); } }
/// <summary> Add a new font specification. </summary> /// <param name="fontSpecification"> The font specification string. <see cref="System.String"/> </param> /// <remarks> Syntax is: "-foundry-family-weight-slant-width-additional style-pixels-tenths of points-horz resolution DPI-vert resolution DPI-spacing-tenths of average pixel width-charter set" </remarks> public void AddFontSpecification(string fontSpecification) { string[] spec = fontSpecification.Split('-'); if (!string.IsNullOrEmpty(spec[0])) { SimpleLog.LogLine(TraceEventType.Warning, CLASS_NAME + "::AddFontSpecification (" + fontSpecification + ") Font specification has leading characters '" + spec[0] + "' but shouldn't."); } if (spec.Length < 14) { SimpleLog.LogLine(TraceEventType.Error, CLASS_NAME + "::AddFontSpecification (" + fontSpecification + ") Font specification contains only " + spec.Length + " parts but must contain 14!"); return; } FontFoundry foundry = GetFoundry(spec[1]); if (foundry == null) { foundry = new FontFoundry(spec[1]); Foundries.Add(foundry); } FontFamily family = foundry.GetFamily(spec[2]); if (family == null) { family = new FontFamily(spec[2], _preferredCharSet); foundry.Families.Add(family); } FontCharacterSet characterSet = family.GetCharacterSet(spec[13], (spec.Length > 14 ? spec[14] : "")); if (characterSet == null) { characterSet = new FontCharacterSet(spec[13], (spec.Length > 14 ? spec[14] : "")); family.CharacterSets.Add(characterSet); } string styleName = FontWeightSlantWidthFlag.ToName(spec[3], spec[4], spec[5], spec[6]); FontWeightSlantWidthFlag weightSlantWidth = characterSet.GetWeightSlantWidthFlag(styleName); if (weightSlantWidth == null) { weightSlantWidth = new FontWeightSlantWidthFlag(spec[3], spec[4], spec[5], spec[6]); characterSet.WeightSlantWidths.Add(weightSlantWidth); } string resolutionName = FontHorzResolutionDpiVertResolutionDpi.ToName(spec[9], spec[10]); FontHorzResolutionDpiVertResolutionDpi resolution = weightSlantWidth.GetHorzResolutionDpiVertResolutionDpi(resolutionName); if (resolution == null) { resolution = new FontHorzResolutionDpiVertResolutionDpi(spec[9], spec[10]); weightSlantWidth.ResolutionDpis.Add(resolution); } string sizeName = FontPixelTenthOfPointSpacingTenthOfAveragePixelWidth.ToName(spec[7], spec[8], spec[11], spec[12]); FontPixelTenthOfPointSpacingTenthOfAveragePixelWidth size = resolution.GetPixelTenthOfPointSpacingTenthOfAveragePixelWidth(sizeName); if (size == null) { size = new FontPixelTenthOfPointSpacingTenthOfAveragePixelWidth(spec[7], spec[8], spec[11], spec[12]); resolution.Sizes.Add(size); } }