Jump to content

  • Log In with Google      Sign In   
  • Create Account


MaulingMonkey

Member Since 18 Aug 2002
Offline Last Active Oct 21 2013 12:01 PM

Topics I've Started

Software for at-a-glance overview / organizing of 9001 Projects?

16 June 2012 - 03:38 AM

I've been digging into my projects\dead\ folder recently, a dumping ground of projects I've stopped working on. There's some stuff well worth salvaging for use in new projects in here. This process is daunting, despite 'only' containing 31,705 files out of the 64,473 files in my projects\ folder.

I want a way to better document my hundreds of throwaway projects. I'm going through, renaming project folders based on language, branch count, adding short descriptions, taking screenshots, etc. -- but this is inefficient, slow, and isn't all that ideal for browsing. I'm after a better at-a-glance view of all my projects. VCS websites like github and sourceforge tend to at least have a project list that lists project names and descriptions -- I'm looking for something similar and more advanced that works locally.

Before I roll my own, is there anything already existing out there? If so, my google-fu is failing me.
Failing that, what are some of the features that could be useful?

Screenshots, Short Descriptions, Tagging, Statistics (language, loc/commit/branch count), Pending changes, VCS and Website tracking all come to mind.

"August" DirectX SDK finally out

09 September 2009 - 11:57 AM

CLICKU The SlimDX team has been notified :P

Uniscribe character placement issues

17 January 2009 - 01:19 PM

I'm at a loss as to what I'm doing wrong.

using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using Uniscribe;
using Uniscribe.Core;

namespace HelloWorld {
	public partial class Form1 : Form {
		private string s = "o";

		public Form1() {
			var t = new Timer();
			t.Tick += new System.EventHandler(t_Tick);
			t.Interval = 500;
			t.Enabled = true;
			InitializeComponent();
		}

		void t_Tick(object sender, System.EventArgs e) {
			s += "o";
			Invalidate();
		}

		private void Form1_Paint(object sender, PaintEventArgs e) {
			// http://www.catch22.net/tuts/neatpad/11

			//string s = "Hello, world!\u064A\u064F\u0633\u0627\u0648\u0650\u064A How are you?";
			//string s = "ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo";

			GDI.SelectObject( e.Graphics, new Font( "Times New Roman", 20.0f ) );
			ScriptStringAnalysis ssa = USP.ScriptStringAnalyse
				( e.Graphics
				, s
				, StringAnalysisFlags.Glyphs | StringAnalysisFlags.Fallback
				, 500
				, null
				, null
				, null
				, null
				, null
				);
			Size size = USP.ScriptStringSize(ssa);
			e.Graphics.DrawRectangle( Pens.Red, new Rectangle( 9, 9, size.Width+1, size.Height+1 ) );
			USP.ScriptStringOut( ssa, 10, 10, StringOutFlags.None, null, 0, 0, false );
			USP.ScriptStringFree( ref ssa );

			// http://www.catch22.net/tuts/neatpad/12

			var control    = new ScriptControl();
			var state      = new ScriptState();
			var items      = USP.ScriptItemize( s, control, state );
			var bidilevels = ( from item in items select (byte)item.a.s.uBidiLevel ).ToArray<byte>();
			//var vtl        = new int[items.Length];
			//USP.ScriptLayout( bidilevels, vtl, null );
			WORD[] glyphs;
			WORD[] logclust;
			ScriptVisAttr[] attrs;
			var analysis   = new ScriptAnalysis();
			var cache      = new ScriptCache();
			USP.ScriptShape( e.Graphics, cache, s, analysis, out glyphs, out logclust, out attrs );
			// TODO:  Font Fallback?
			int[] advance;
			GOFFSET[] goffsets;
			ABC abc;
			USP.ScriptPlace( e.Graphics, cache, glyphs, attrs, analysis, out advance, out goffsets, out abc );
			USP.ScriptTextOut( e.Graphics, cache, 10, 110, StringOutFlags.None, null, analysis, glyphs, advance, null, new GOFFSET() );
		}
	}
}







A simple pair of tests of Uniscribe -- the top section using the higher level ScriptString* series of functions and rendering correctly, the bottom selection using the more versatile basic functions exploding horribly:



I have no idea what I'm doing wrong. Unfortunately, there's a large bulk of code that could be suspect. All the arrays seem to be the right size, goffsets is full of (0,0)s, advances is also full of 0s, glyphs is all a single value (the o glyph), logclust increments normally (logclust[i] = i since everything is LTR and we have a 1:1 character to glyph mapping), and we have one "items".

I'm running out of ideas as to what could be wrong. I've double checked that each Uniscribe.Core.* class/structure/function matches it's usp10.h equivalent.

Some relevant functions:
namespace Uniscribe {
	[StructLayout(LayoutKind.Sequential)]
	public class OptionalBase {}

	[StructLayout(LayoutKind.Sequential)]
	public class Optional<T> : OptionalBase where T:struct {
		public T Value;
	}
	public static class OptionalExtensionMethods {
		public static OptionalBase AsOptional<T>( this T? value ) where T:struct {
			return (value != null && value.HasValue)
				? new Optional<T>() { Value = value.Value }
				: null
				;
		}
	}

	public partial class USP {
		// http://msdn.microsoft.com/en-us/library/ms776521(VS.85).aspx

		[DllImport("usp10.dll",CharSet=CharSet.Unicode,PreserveSig=false)]
		static extern void ScriptItemize
			( [In]  string        pwcInChars
			, [In]  int           cInChars
			, [In]  int           cMaxItems
			, [In]  ScriptControl psControl
			, [In]  ScriptState   psState
			, [Out] ScriptItem[]  pItems
			,  out  int           pcItems
			);

		public static ScriptItem[] ScriptItemize
			( string s
			, ScriptControl control
			, ScriptState   state
			)
		{
			ScriptItem[] items = new ScriptItem[2];
			int nitems = 0;
			
			for (int max = 1000 ; max > 0 ; --max ) try {
				ScriptItemize( s, s.Length, items.Length, control, state, items, out nitems );
				nitems += 1; // nitems doesn't include the terminal item by default
				ScriptItem[] result = new ScriptItem[ nitems ];
				Array.Copy( items, result, nitems );
				return result;
			} catch ( OutOfMemoryException ) { // thrown by ScriptItemize if items wasn't large enough
				items = new ScriptItem[ items.Length*3/2 ];
				continue;
			}

			throw new ApplicationException
				( "Infinite loop detected -- was trying to turn a "
				+ items.Length
				+ " length string into (at most) "
				+ items.Length
				+ " items at last attempt."
				);
		}


		// http://msdn.microsoft.com/en-us/library/ms776517(VS.85).aspx

		[DllImport("usp10.dll",CharSet=CharSet.Unicode,PreserveSig=false)]
		extern static void ScriptShape
			( [In]     IntPtr          hdc
			, [In,Out] ScriptCache     psc
			, [In]     string          pwcChars
			, [In]     int             cChars
			, [In]     int             cMaxGlyphs
			, [In,Out] ScriptAnalysis  psa
			, [Out]    WORD[]          pwOutGlyphs
			, [Out]    WORD[]          pwLogClust
			, [Out]    ScriptVisAttr[] psva
			,  out     int             pcGlyphs
			);

		public static void ScriptShape
			(     IDeviceContext  hdc
			,     ScriptCache     cache
			,     string          s
			,     ScriptAnalysis  psa
			, out WORD[]          pwOutGlyphs
			, out WORD[]          pwLogClust
			, out ScriptVisAttr[] psva
			)
		{
			int maxglyphs = s.Length*3/2+16;
			int nglyphs;
			pwLogClust = new WORD[s.Length];

			for ( int max = 1000 ; max > 0 ; --max ) {
				var glyphs = new WORD[maxglyphs];
				var attrs = new ScriptVisAttr[maxglyphs];
				try {
					ScriptShape( hdc.GetHdc(), cache, s, s.Length, maxglyphs, psa, glyphs, pwLogClust, attrs, out nglyphs );
					pwOutGlyphs = new WORD[nglyphs];
					psva = new ScriptVisAttr[nglyphs];
					Array.Copy( glyphs, pwOutGlyphs, nglyphs );
					Array.Copy( attrs, psva, nglyphs );
					return;
				} catch ( OutOfMemoryException ) {
					maxglyphs = maxglyphs*3/2;
					continue;
				} finally {
					hdc.ReleaseHdc();
				}
			}

			throw new ApplicationException
				( "Infinite loop detected -- was trying to turn a "
				+ s.Length
				+ " length string into (at most) "
				+ maxglyphs
				+ " glyphs at last attempt."
				);
		}


		// http://msdn.microsoft.com/en-us/library/ms776477(VS.85).aspx

		[DllImport("usp10.dll",PreserveSig=false)]
		static extern void ScriptPlace
			( [In]     IntPtr          hdc
			, [In,Out] ScriptCache     psc
			, [In]     WORD[]          pwGlyphs
			, [In]     int             cGlyphs
			, [In]     ScriptVisAttr[] psva
			, [In,Out] ScriptAnalysis  psa
			, [Out]    int[]           piAdvance
			, [Out]    GOFFSET[]       goffset
			,  out     ABC             pABC
			);

		public static void ScriptPlace
			(     IDeviceContext  hdc
			,     ScriptCache     psc
			,     WORD[]          pwGlyphs
			,     ScriptVisAttr[] psva
			,     ScriptAnalysis  psa
			, out int[]           piAdvance
			, out GOFFSET[]       goffset
			, out ABC             pABC
			)
		{
			piAdvance = new int[pwGlyphs.Length];
			goffset   = new GOFFSET[pwGlyphs.Length];

			ScriptPlace( hdc.GetHdc(), psc, pwGlyphs, pwGlyphs.Length, psva, psa, piAdvance, goffset, out pABC );
			hdc.ReleaseHdc();
		}


		// http://msdn.microsoft.com/en-us/library/ms776504(VS.85).aspx

		[DllImport("usp10.dll", PreserveSig=false)]
		static extern void ScriptTextOut
			( [In]     IntPtr         hdc
			, [In,Out] ScriptCache    psc
			, [In]     int            x
			, [In]     int            y
			, [In]     StringOutFlags flags
			, [In]     OptionalBase   lprc
			, [In]     ScriptAnalysis psa
			, [In]     IntPtr         pwcReserved // const WCHAR* -- Reserved; must be a null pointer.
			, [In]     int            iReserved      // Reserved; must be 0.
			, [In]     WORD[]         pwGlyphs
			, [In]     int            cGlyphs
			, [In]     int[]          piAdvance
			, [In]     int[]          piJustify
			, [In] ref GOFFSET        goffset
			);

		public static void ScriptTextOut
			( IDeviceContext hdc
			, ScriptCache psc
			, int x
			, int y
			, StringOutFlags flags
			, Rect? lprc
			, ScriptAnalysis analysis
			, WORD[] pwGlyphs
			, int[] piAdvance
			, int[] piJustify
			, GOFFSET goffset
			)
		{
			try {
				ScriptTextOut
					( hdc.GetHdc()
					, psc
					, x
					, y
					, flags
					, lprc.AsOptional()
					, analysis
					, IntPtr.Zero
					, 0
					, pwGlyphs
					, pwGlyphs.Length
					, piAdvance
					, piJustify
					, ref goffset
					);
			} finally {
				hdc.ReleaseHdc();
			}
		}
	}
	public partial class GDI {
		// http://msdn.microsoft.com/en-us/library/ms533272(VS.85).aspx
		
		[DllImport("gdi32.dll")]
		public static extern IntPtr SelectObject
			( IntPtr hdc
			, IntPtr hgdiobj
			);

		public static void SelectObject
			( IDeviceContext hdc
			, Font hgdiobj
			)
		{
			var prev = SelectObject( hdc.GetHdc(), hgdiobj.ToHfont() );
			hdc.ReleaseHdc();
			//return Font.FromHfont(prev); // System.Drawing.Font only supports truetype
		}
	}
}








And some structures:

using System;
using System.Drawing;
using System.Runtime.InteropServices;
using Uniscribe.Core;

namespace Uniscribe {
	namespace Core {
		/// <summary>
		/// Equivalent to SCRIPT_STRING_ANALYSIS, which is an opaque typedef (to void*)
		/// http://msdn.microsoft.com/en-us/library/ms776471(VS.85).aspx
		/// </summary>
		[StructLayout(LayoutKind.Sequential)] public struct ScriptStringAnalysis {
			IntPtr ptr;
		}

		/// <summary>
		/// Equivalent to a SCRIPT_CACHE*, where SCRIPT_CACHE is an opaque typedef (to void*)
		/// http://msdn.microsoft.com/en-us/library/ms776467(VS.85).aspx
		/// </summary>
		[StructLayout(LayoutKind.Sequential)] public class ScriptCache {
			IntPtr ptr;
		}
		
		/// <summary>
		/// Equivalent to a COLORREF, which is a typedef to a DWORD
		/// http://msdn.microsoft.com/en-us/library/ms532655(VS.85).aspx
		/// </summary>
		[StructLayout(LayoutKind.Sequential)] public struct ColorRef {
			// COLORREF is a typedef to DWORD
			uint Value; // 0x00BBGGRR

			public byte Blue  { get { return (byte)((Value>>16) & 0xFF); } set { Value = Value&0xFF00FFFF + value<<16; } }
			public byte Green { get { return (byte)((Value>> 8) & 0xFF); } set { Value = Value&0xFFFF00FF + value<< 8; } }
			public byte Red   { get { return (byte)((Value>> 0) & 0xFF); } set { Value = Value&0xFFFFFF00 + value<< 0; } }

			public static ColorRef From( Color c ) { return new ColorRef() { Value = (uint)(c.B << 16 + c.G << 8 + c.R << 0) }; }
			public Color ToColor() { return Color.FromArgb( Red, Green, Blue ); }

			public static ColorRef Invalid = new ColorRef() { Value = 0xFFFFFFFF }; // == CLR_INVALID
		}

		/// <summary>
		/// Equivalent to a SCRIPT_STATE*
		/// http://msdn.microsoft.com/en-us/library/ms776530(VS.85).aspx
		/// </summary>
		[StructLayout(LayoutKind.Sequential)]
		public class ScriptState {
			public WORD Data;

			public int  uBidiLevel         { get { return (Data.Value & 0x001F) >> 0; } }
			public bool fOverrideDirection { get { return (Data.Value & 0x0020) != 0; } }
			public bool fInhibitSymSwap    { get { return (Data.Value & 0x0040) != 0; } }
			public bool fCharShape         { get { return (Data.Value & 0x0080) != 0; } }
			public bool fDigitSubstitute   { get { return (Data.Value & 0x0100) != 0; } }
			public bool fInhibitLigate     { get { return (Data.Value & 0x0200) != 0; } }
			public bool fDisplayZWG        { get { return (Data.Value & 0x0400) != 0; } }
			public bool fArabicNumContext  { get { return (Data.Value & 0x0800) != 0; } }
			public bool fGcpClusters       { get { return (Data.Value & 0x1000) != 0; } }
			// WORD fReserved : 1
			// WORD fEngineReserved : 2
		}

		/// <summary>
		/// Equivalent to a SCRIPT_VISATTR
		/// http://msdn.microsoft.com/en-us/library/ms776515(VS.85).aspx
		/// </summary>
		[StructLayout(LayoutKind.Sequential)]
		public struct ScriptVisAttr {
			WORD data;
			public int  uJustification { get { return (data.Value & 0x000F) >> 0; } }
			public bool fClusterStart  { get { return (data.Value & 0x0010) != 0; } }
			public bool fDiacritic     { get { return (data.Value & 0x0020) != 0; } }
			public bool fZeroWidth     { get { return (data.Value & 0x0040) != 0; } }
			// WORD fReserved : 1
			// WORD fShapeReserved : 8
		}

		/// <summary>
		/// Equivalent to a SCRIPT_ANALYSIS*
		/// http://msdn.microsoft.com/en-us/library/ms776520(VS.85).aspx
		/// </summary>
		[StructLayout(LayoutKind.Sequential)]
		public class ScriptAnalysis {
			public WORD Data;

			public int  eScript       { get { return (Data.Value & 0x03FF) >> 0; } }
			public bool fRTL          { get { return (Data.Value & 0x0400) != 0; } }
			public bool fLayoutRTL    { get { return (Data.Value & 0x0800) != 0; } }
			public bool fLinkBefore   { get { return (Data.Value & 0x1000) != 0; } }
			public bool fLinkAfter    { get { return (Data.Value & 0x2000) != 0; } }
			public bool fLogicalOrder { get { return (Data.Value & 0x4000) != 0; } }
			public bool fNoGlyphIndex { get { return (Data.Value & 0x8000) != 0; } }

			WORD sdata; // corresponds to SCRIPT_STATE member "SCRIPT_STATE s;"
			public ScriptState s {
				get { return new ScriptState() { Data = sdata }; }
				set { sdata = value.Data; }
			}
		}

		/// <summary>
		/// Equivalent to a SCRIPT_CONTROL*
		/// http://msdn.microsoft.com/en-us/library/ms776493(VS.85).aspx
		/// </summary>
		[StructLayout(LayoutKind.Sequential)]
		public class ScriptControl {
			DWORD data;
			public int  uDefaultLanguage    { get { return (int)(data.Value & 0x0000FFFF) >> 0; } }
			public bool fContextDigits      { get { return (data.Value & 0x00010000) != 0; } }
			public bool fInvertPreBoundDir  { get { return (data.Value & 0x00020000) != 0; } }
			public bool fInvertPostBoundDir { get { return (data.Value & 0x00040000) != 0; } }
			public bool fLinkStringBefore   { get { return (data.Value & 0x00080000) != 0; } }
			public bool fLinkStringAfter    { get { return (data.Value & 0x00100000) != 0; } }
			public bool fNeutralOverride    { get { return (data.Value & 0x00200000) != 0; } }
			public bool fNumericOverride    { get { return (data.Value & 0x00400000) != 0; } }
			public bool fLegacyBidiClass    { get { return (data.Value & 0x00800000) != 0; } }
			public bool fMergeNeutralItems  { get { return (data.Value & 0x01000000) != 0; } }
			// DWORD fReserved : 7
		}

		/// <summary>
		/// Equivalent to a SCRIPT_ITEM
		/// http://msdn.microsoft.com/en-us/library/ms776513(VS.85).aspx
		/// </summary>
		[StructLayout(LayoutKind.Sequential)]
		public struct ScriptItem {
			public int iCharPos;
			private WORD aData; // corresponds to SCRIPT_ITEM member "SCRIPT_ANALYSIS a;"
			public ScriptAnalysis a { get { return new ScriptAnalysis() { Data = aData }; } set { aData = value.Data; } }
		}


		/// <summary>
		/// Stronger typed flags for ScriptStringAnalyse's parameter, DWORD dwFlags.
		/// ScriptStringAnalyse's documentation: http://msdn.microsoft.com/en-us/library/ms776516(VS.85).aspx
		/// </summary>
		public enum StringAnalysisFlags : uint {
			None       =      0,
			Break      = 0x0040, //SSA_BREAK       Return break flags, that is, character and word stops.
			Clip       = 0x0004, //SSA_CLIP        Clip the string at iReqWidth.
			DZWG       = 0x0010, //SSA_DZWG        Provide representation glyphs for control characters.
			Fallback   = 0x0020, //SSA_FALLBACK    Use fallback fonts.
			Fit        = 0x0008, //SSA_FIT         Justify the string to iReqWidth.
			Glyphs     = 0x0080, //SSA_GLYPHS      Generate glyphs, positions, and attributes.
			GCP        = 0x0200, //SSA_GCP         Return missing glyphs and pwLogClust with GetCharacterPlacement conventions.
			HideHotKey = 0x2000, //SSA_HIDEHOTKEY  Remove the first '&' from displayed string.
			HotKey     = 0x0400, //SSA_HOTKEY      Replace '&' with underline on subsequent code point.
			HotKeyOnly = 0x2400, //SSA_HOTKEYONLY  Display underline only. [EDIT: *snip*]
			Link       = 0x1000, //SSA_LINK        Apply East Asian font linking and association to noncomplex text.
			Metafile   = 0x0800, //SSA_METAFILE    Write items with ExtTextOutW calls, not with glyphs.
			Password   = 0x0001, //SSA_PASSWORD    Duplicate input string containing a single character tcString times.
			RTL        = 0x0100, //SSA_RTL         Use base embedding level 1.
			Tab        = 0x0002, //SSA_TAB         Expand tabs.
		}

		/// <summary>
		/// Stronger typed flags for the parameter, UINT uOptions, in various functions:
		///   ScriptStringOut's documentation: http://msdn.microsoft.com/en-us/library/ms776499(VS.85).aspx
		///   ScriptTextOut's documentation:   http://msdn.microsoft.com/en-us/library/ms776504(VS.85).aspx
		/// </summary>
		public enum StringOutFlags : uint {
			None    =      0,
			Opaque  = 0x0002, // ETO_OPAQUE
			Clipped = 0x0004, // ETO_CLIPPED
		}


		/// <summary>
		/// Corresponds to RECT
		/// http://msdn.microsoft.com/en-us/library/ms536136(VS.85).aspx
		/// </summary>
		[StructLayout(LayoutKind.Sequential)]
		public struct Rect {
			public long Left;
			public long Top;
			public long Right;
			public long Bottom;

			public long Width  { get { return Right-Left; } } // [Left..Right)
			public long Height { get { return Bottom-Top; } } // [Top..Bottom)

			public override string ToString() {
				return Left + "," + Top + "," + Right + "," + Bottom;
			}
		}

		/// <summary>
		/// Corresponds to GOFFSET
		/// http://msdn.microsoft.com/en-us/library/ms776514(VS.85).aspx
		/// </summary>
		[StructLayout(LayoutKind.Sequential)]
		public struct GOFFSET {
			public long DU;
			public long DV;

			public long DX { get { return DU; } set { DU = value; } }
			public long DY { get { return DV; } set { DV = value; } }

			public override string ToString() {
				return DU + "," + DV;
			}
		}

		/// <summary>
		/// Corresponds to ABC
		/// http://msdn.microsoft.com/de-de/library/8e350930.aspx
		/// </summary>
		[StructLayout(LayoutKind.Sequential)]
		public struct ABC {
			public int abcA;
			public uint abcB;
			public int abcC;

			public override string ToString() {
				return abcA + "," + abcB + "," + abcC;
			}
		}



		[StructLayout(LayoutKind.Sequential)] public struct WORD  {
			public ushort Value;
			public override string ToString() { return Value.ToString(); }
		} // WORD is a typedef
		[StructLayout(LayoutKind.Sequential)] public struct DWORD {
			public uint   Value;
			public override string ToString() { return Value.ToString(); }
		} // DWORD is a typedef
	}
}







EDIT: Tried to unbreak the forum width a little bit

And, yes, I'm aware I'm leaking a bit (e.g. SCRIPT_CACHE is supposed to get ScriptCacheFree()d)

Bit based fractional number system terminology?

30 May 2007 - 06:38 PM

I'm looking for a term to put a particular class of numerical representation under. It would fill in the blank here, were we trying to represent the range [0, 1]:
Bit Pattern         |  000    001    010    011    100    101    110    111   |
-------------------------------------------------------------------------------
Fixed point (1.2)   | 0.00    .25    .50    .75   1.00   1.25   1.50   1.75   | -> overshoots the [0, 1] representation range (wasteful)
Fixed point (0.3)   | 0.00    .125   .25    .375   .50    .625   .75    .875  | -> undershoots the [0, 1] representation range
  ??? (fractional)  |  0/7    1/7    2/7    3/7    4/7    5/7    6/7    7/7   | -> what is this? (1.0 == 11111111b == full white in graphics?)
  ??? (approximate) | 0.000  0.143  0.285  0.428  0.571  0.714  0.857  1.000  |
-------------------------------------------------------------------------------
For N bits, each column is 2i * N/(N-1) where i is an integer. Unlike normal numbering systems, there is no ones column. In this case, there's a 4/7ths column, a 2/7ths column, and a 1/7ths column. There would be a 8/7ths column if we extended this representation past 1. Anyone fill in the ??? for me?

SPARTA!!!

13 May 2007 - 06:19 AM

Let's just leave it at this:
Free Image Hosting at www.ImageShack.us

PARTNERS