I need to get the available OpenType features for a given font in my app (C#). I'm using DirectWrite through SharpDX and I'm having a really bad time.
I know that the best solution is to use this method:
SharpDX.DirectWrite.TextAnalyzer2.GetTypographicFeatures
but I don't know how to get a result from it, as I don't know where to get the parameters.
These are the parameters I need to provide in order to get the Font Features:
fontFace FontFace
scriptAnalysis ScriptAnalysis
localName String
maxTagCount int
actualTagCount int
tags FontFeatureTag
Can someone please provide me a better explanation or (ideally) some code. There is almost no documentation about it so I don't know where I can get these parameters and/or what they mean.
Thanks in advance.
I figure it out lastly. Thanks to Buglehead who gave me the final piece of the puzzle.
Here is an example. In this code I first load all system fonts, then get a specific font, and then get the FontFeatureTags for that specific font.
using SharpDX.DirectWrite;
private void LoadFontFeatureTags()
{
Factory f = new Factory(FactoryType.Isolated);
Factory4 _factory = new Factory4(f.NativePointer);
_factory.CreateFontCollectionFromFontSet(_factory.SystemFontSet, out FontCollection1 collection);
List<SharpDX.DirectWrite.FontFamily> loadedFonts = new List<SharpDX.DirectWrite.FontFamily>();
for (int i = 0; i < collection.FontFamilyCount; i++)
{
var family = collection.GetFontFamily(i);
loadedFonts.Add(family);
}
var gabriolaFont = loadedFonts.FirstOrDefault(x => x.FamilyNames.GetString(0).Contains("Gabriola"));
var gabriolaFirstChild = gabriolaFont.GetFont(0);
Font3 f3 = new Font3(gabriolaFirstChild.NativePointer);
f3.CreateFontFace(out FontFace3 face3);
ScriptAnalysis analysis = new ScriptAnalysis();
TextAnalyzer analyzer = new TextAnalyzer(f);
TextAnalyzer2 analyzer2 = new TextAnalyzer2((IntPtr)analyzer);
int maxTagCount = 32;
FontFeatureTag[] featuresArray = new FontFeatureTag[maxTagCount];
analyzer2.GetTypographicFeatures(face3, analysis, "es-US", maxTagCount, out int actualCount, featuresArray);
}
Related
I'am using [Akka.Net 1.3.1] a mix of ReceiveActors and ReceivePersistentActors and now I want to write tests for my actorsystem.
MyPersistentActor inherits from ReceivePersistentActor and MyActor inherits from ReceiveActor.
I also installed Akka.TestKit using version 1.3.1 .
But it seems that only ReceiveActors can be tested by Akka.TestKit.
IActorRef myActorRef = this.Sys.ActorOf<MyActor>(); // is fine
IActorRef myPersistentActorRef = this.Sys.ActorOf<MyPersistentActor>(); // is a problem
I also found the nuget package Akka.Persistence.TestKit version 1.2.3.43-beta . The beta wasn't changed since three month and only support akka 1.2.2 . Is it still in development or is it dead. I can not find any kind of information regarding that.
How do you test your persistent actors?
Thanks for your help!
Richi
Akka.Persistence.TestKit has been renamed to Akka.Persistence.TCK and it is used only for testing custom event journal and snapshot store implementations for compatibility with Akka.Persistence protocol. It doesn't bring any utilities for testing user actors.
There are no built-in methods to cooperate with journals/snapshot stores for testing purposes beside having implementations of them working in-memory. With that being said, you can actually work with journal/snapshot store just like with any other actor. If you look into implementations of persistence TCK specs like JournalSpec, you may get some insights into how that protocol works.
For example, if you want to initialize your journal with some events before firing the test case, you can do it like following:
void InitWithEvents(string persistenceId, params object[] events)
{
var probe = CreateTestProbe();
var writerGuid = Guid.NewGuid().ToString();
var writes = new AtomicWrite[events.Length];
for (int i = 0; i < events.Length; i++)
{
var e = events[i];
writes[i] = new AtomicWrite(new Persistent(e, i+1, persistenceId, "", false, ActorRefs.NoSender, writerGuid));
}
var journal = Persistence.Instance.Apply(Sys).JournalFor(null);
journal.Tell(new WriteMessages(writes, probe.Ref, 1));
probe.ExpectMsg<WriteMessagesSuccessful>();
for (int i = 0; i < events.Length; i++)
probe.ExpectMsg<WriteMessageSuccess>();
}
PS: There is clearly a missing part in the persistence TestKit API, any contributions on that field are more than welcome.
I know this is an ols answer, but I couldn't find any better resource. In my tests I am actually only interested if the correct event(s) is (are) persisted after I give my command. Multiple events could be raised by starting a saga. Most of the time I am only interested in the last persisted event.
If somebody is hitting the same issue as me, this is how I fixed getting the last message, based on Bartosz initWithEvents.
private void InitWithEvents(string persistenceId, IList<object> events)
{
var probe = CreateTestProbe();
var writerGuid = Guid.NewGuid().ToString();
var writes = new AtomicWrite[events.Count];
for (int i = 0; i < events.Count; i++)
{
var e = events[i];
writes[i] = new AtomicWrite(new Persistent(e, i+1, persistenceId, "", false, ActorRefs.NoSender, writerGuid));
}
journal = Persistence.Instance.Apply(Sys).JournalFor(null);
journal.Tell(new WriteMessages(writes, probe.Ref, 1));
probe.ExpectMsg<WriteMessagesSuccessful>();
for (int i = 0; i < events.Count; i++)
probe.ExpectMsg<WriteMessageSuccess>();
}
private object GetLastPersistedMessageFromJournal(string persistenceId)
{
var repointable = journal as RepointableActorRef;
var underlying = repointable.Underlying as ActorCell;
PropertyInfo prop = typeof(ActorCell).GetProperty("Actor", BindingFlags.NonPublic | BindingFlags.Instance);
MethodInfo getter = prop.GetGetMethod(nonPublic: true);
MemoryJournal jrnl = getter.Invoke(underlying, null) as MemoryJournal;
var read = jrnl?.Read(persistenceId, 0, Int64.MaxValue, Int64.MaxValue);
return read?.Last().Payload;
}
I'm new to Ektron, and I'm having trouble finding decent documentation on how to get content. I have a folder that contains smartforms. In my code, I need to get all those smartforms. This is all I have so far:
var folderManager = new FolderManager();
var folder = folderManager.GetTree(Convert.ToInt64(ConfigurationManager.AppSettings["AlumniSlideshowFolderId"]));
But from there, I have no idea how to get my data. Please help!
Something like this should do the trick. You'll actually want to use the ContentManager instead of the FolderManager. The criteria object is pretty powerful... you can refine the list down further if you need to.
var contentManager = new ContentManager();
int recordsPerPage;
int.TryParse(ConfigurationManager.AppSettings["AlumniSlideshow.RecordsPerPage"], out recordsPerPage);
int currentPage;
int.TryParse(HttpContext.Current.Request.QueryString["p"], out currentPage);
if (currentPage <= 0)
{
currentPage = 1;
}
long alumniSlideshowFolderId;
long.TryParse(ConfigurationManager.AppSettings["AlumniSlideshowFolderId"], out alumniSlideshowFolderId);
var criteria = new ContentCriteria();
criteria.AddFilter(ContentProperty.FolderId, CriteriaFilterOperator.EqualTo, alumniSlideshowFolderId);
// By default, the GetList method will use a 'recordsPerPage' value of 50.
criteria.PagingInfo = new PagingInfo(recordsPerPage, currentPage);
var content = contentManager.GetList(criteria);
foreach (var contentData in content)
{
// work with each result here
}
You also mentioned not finding good documentation. Here are a few links. There is some pretty good documentation available, especially for the newer FrameworkAPI classes. You just have to know where to look.
http://documentation.ektron.com/cms400/edr/web/edr.htm
http://documentation.ektron.com/cms400/edr/web/Content/FrameworkAPI/Content/ContentManager.htm
I'm currently working on a basic drawing program. One of the requirements is to be able to save the list of drawn objects and load it back in. So far, I have written a save function that exports all items of the list to an XML format, and I'm currently working on the loading-part.
Whenever the program encounters a "< RechthoekTool >" (Dutch for RectangleTool), it executes the following code:
//Create new tool.
RechthoekTool tool = new RechthoekTool();
//Turn <Startpoint> and <Endpoint> into actual points
var sp = Regex.Replace(xn["Startpunt"].InnerText, #"[\{\}a-zA-Z=]", "").Split(',');
tool.startpunt = new Point(int.Parse(sp[0]), int.Parse(sp[1]));
var ep = Regex.Replace(xn["Eindpunt"].InnerText, #"[\{\}a-zA-Z=]", "").Split(',');
tool.eindpunt = new Point(int.Parse(ep[0]), int.Parse(ep[1]));
//Set colour and width of brush
string kleur = xn["Dikte"].InnerText;
kleur.Replace(#"Color [", "");
kleur.Replace(#"]", "");
Color c = Color.FromName(kleur);
tool.kwastkleur = c;
tool.kwast = new SolidBrush(c);
tool.dikte = int.Parse(xn["Dikte"].InnerText);
//Add to list
s.listItems.Add(tool);
Whenever I run the program, I get the 'NullReferenceException was unhandled' error("Object reference not set to an instance of an object.") at
s.listItems.Add(tool);
I do, however, instantiate the tool right at the beginning, don't I? What could be causing this error? Some Googling told me it might be because I forgot to assign a property, but as far as I can tell I've got them all covered...
Help would be greatly appreciated.
The error is due to s or s.listItems not being instantiated.
Without seeing more code, it's difficult to know which is null, but at a guess you are creating a new object for s, which contains a property/field listItems, but you aren't assigning a list to listItems.
The problem is that you aren't instantiating listItems or s. Not enough information is given to tell you how to instantiate s but you can do the other one like this:
s.listItems = new List<RechthoekTool>();
If you don't instantiate something using the new keyword; it simply won't work.
Using your code, try this:
//Create new tool.
RechthoekTool tool = new RechthoekTool();
//Turn <Startpoint> and <Endpoint> into actual points
var sp = Regex.Replace(xn["Startpunt"].InnerText, #"[\{\}a-zA-Z=]", "").Split(',');
tool.startpunt = new Point(int.Parse(sp[0]), int.Parse(sp[1]));
var ep = Regex.Replace(xn["Eindpunt"].InnerText, #"[\{\}a-zA-Z=]", "").Split(',');
tool.eindpunt = new Point(int.Parse(ep[0]), int.Parse(ep[1]));
//Set colour and width of brush
string kleur = xn["Dikte"].InnerText;
kleur.Replace(#"Color [", "");
kleur.Replace(#"]", "");
Color c = Color.FromName(kleur);
tool.kwastkleur = c;
tool.kwast = new SolidBrush(c);
tool.dikte = int.Parse(xn["Dikte"].InnerText);
List<RechthoekTool> s = new List<RechthoekTool>(); // You can now use your list.
//Add to list
s.listItems.Add(tool);
Suppose I have a program which allows a user to upload any kind of file. Along with getting generic information such as file type and file size, I would like to attempt to grab any extra information (such as document properties like author, last revised, etc) that may be transported along with the document.
Since I don't have any knowledge about the incoming document/file ahead of time, I can't simply use classes that are specific to, say Microsoft Office docs. I need to do this generically and then construct a dynamic object or dictionary to hold any found key/value results.
Is this possible? If so, how? Any help is appreciated!
I found a few answers on StackOverflow for this, but none gave me a nice, clean dictionary of document properties. Here is what I finally came up with and it seems to be working nicely (you will need to reference "Microsoft Shell Controls and Automation" from the COM folder and add using Shell32; to your code:
public static Dictionary<string,string> GetDocumentMetadata(string fileName)
{
var properties = new Dictionary<string,string>();
var arrHeaders = new List<string>();
var shell = new Shell();
var objFolder = shell.NameSpace(HttpContext.Current.Server.MapPath("~/RawFiles"));
var file = objFolder.ParseName(fileName);
for (var i = 0; i < short.MaxValue; i++)
{
var header = objFolder.GetDetailsOf(null, i);
if (String.IsNullOrEmpty(header))
break;
arrHeaders.Add(header);
}
for (var i = 0; i < arrHeaders.Count; i++)
{
var value = objFolder.GetDetailsOf(file, i);
if (!String.IsNullOrEmpty(value))
{
properties.Add(arrHeaders[i], value);
}
}
return properties;
}
Using the Visual Studio C# Winforms Google Earth plugin, 4 placemarks have been added to the globe as can be seen in the picture below:
My goal is to be able to remove the linestring placemark. The steps would seem to be to get all the placemarks, find the linestring and remove it.
Here is the code being used to create the linestring placemarks (more or less from the API website)
var lineStringPlacemark = ge2.createPlacemark("Line_" + name);
// create the line string geometry
var lineString = ge2.createLineString("");
lineStringPlacemark.setGeometry(lineString);
// add the the points to the line string geometry
double dlat1 = Convert.ToDouble(lat1) / 100000;
double dlon1 = Convert.ToDouble(lon1) / 100000;
double dlat2 = Convert.ToDouble(lat2) / 100000;
double dlon2 = Convert.ToDouble(lon2) / 100000;
lineString.getCoordinates().pushLatLngAlt(dlat1, dlon1, 0);
lineString.getCoordinates().pushLatLngAlt(dlat2, dlon2, 0);
// Create a style and set width and color of line
lineStringPlacemark.setStyleSelector(ge2.createStyle(""));
var lineStyle = lineStringPlacemark.getStyleSelector().getLineStyle();
lineStyle.setWidth(5);
lineStyle.getColor().set("9900ffff"); // aabbggrr format
// Add the feature to Earth
ge2.getFeatures().appendChild(lineStringPlacemark);
And here is the code I ended up using to remove the line. Note that the GEHelpers.RemoveFeatureById(ge2, s); is commented out since it isn't working for me for some reason.
for (int i = 0; i < ge2.getFeatures().getChildNodes().getLength(); i++)
{
var kmlobject = ge2.getFeatures().getChildNodes().item[i];
string s = kmlobject.getId();
if (s.Contains("Line_"))
{
ge2.getFeatures().removeChild(kmlobject);
kmlobject.release();
//GEHelpers.RemoveFeatureById(ge2, s);
}
}
The line you have should work and remove all the currently loaded content.
GEHelpers.RemoveAllFeatures(ge); // removes all loaded features from 'ge'
If you wish to remove a specific placemark, or any other feature, simply specify its ID as the parameter to the RemoveFeatureById method.
GEHelpers.RemoveFeatureById(ge, 'foo'); // remove the feature with the id 'foo'
An ID can be set either when you create the feature via the api or when you define the feature in kml. e.g.
// api
ge.createPlacemark('foo');
//kml id
<Document id="foo">
</Document>
Edit:
You should not have to do anything other than...
for (int i = 0; i < ge2.getFeatures().getChildNodes().getLength(); i++)
{
var kmlobject = ge2.getFeatures().getChildNodes().item[i];
if (kmlobject.getId().Contains("Line_"))
{
ge2.getFeatures().removeChild(kmlobject);
}
}
I think that there is possibly something else going on with your set up, maybe to do with having multiple instances of the plugin running at the same time.