I have a question regarding conventions on using do blocks in F#. Primarily this comes up when working with the .NET library classes and other .NET code.
Let me give you an example.
1. With a do block wrapped around statements:
let drawHelloName (width:int, height:int) name =
let bmp = new Bitmap(width, height)
use fnt = new Font("Arial", 12.0f)
use gr = Graphics.FromImage(bmp)
do
gr.Clear(Color.White)
gr.DrawString(name, fnt, Brushes.Black, PointF(10.0f, 10.0f))
bmp
2. Without a do block:
let drawHelloName (width:int, height:int) name =
let bmp = new Bitmap(width, height)
use fnt = new Font("Arial", 12.0f)
use gr = Graphics.FromImage(bmp)
gr.Clear(Color.White)
gr.DrawString(name, fnt, Brushes.Black, PointF(10.0f, 10.0f))
bmp
Now in my mind I think example 1 is clearer and more to the point and style of F#. Since it's not really "natural" to work with statements in functional programming, we explicitly wrap the statements in a do block to show that they are side-effects. But I am wondering, what is the convention regarding this?
Since it's not really "natural" to work with statements in functional programming, we explicitly wrap the statements in a do block to show that they are side-effects.
I agree with you. However, if you look into F# code in the wild, they tend to be loose in that matter. There is no strict convention, just follow what you think is the best suitable for you.
Another point is that do blocks create new scopes for values that we would like to explicitly control their lifetimes. For example, if you would like to dispose gr earlier and continue to use fnt, your first function can be written to:
let drawHelloName (width:int, height:int) name =
let bmp = new Bitmap(width, height)
use fnt = new Font("Arial", 12.0f)
do
use gr = Graphics.FromImage(bmp)
gr.Clear(Color.White)
gr.DrawString(name, fnt, Brushes.Black, PointF(10.0f, 10.0f))
(* Continue to do something with 'fnt' *)
bmp
Another place where you have to use do blocks is inside implicit constructors e.g.
type T(width, height) =
let bmp = new Bitmap(width, height)
use fnt = new Font("Arial", 12.0f)
use gr = Graphics.FromImage(bmp)
do
gr.Clear(Color.White)
gr.DrawString(name, fnt, Brushes.Black, PointF(10.0f, 10.0f))
Related
I have two rectangles, one that is occasionally reset to some other rectangle. In C++ I'd just do:
_rect = _resetRect;
But in Dart that actually means that _rect now refers to the same object as _resetRect which is not what I want.
My current solution is this:
_rect.left = _resetRect.left;
_rect.width = _resetRect.width;
_rect.top = _resetRect.top;
_rect.height = _resetRect.height;
This is idiotic. Other questions suggest that there is no built-in way to copy objects (like there is in C++), and you have to rely on the object providing a clone() method. But Rectangle doesn't have one so what do I do?
Also even if it did have a clone() method, wouldn't that allocate an entirely new Rectangle rather than just setting the fields of the existing one (like C++'s operator=), and therefore be less efficient?
C++ also does not have a way to deep-copy an object which contains pointers/references to other objects. In Dart, all values are references, so that restriction applies to all objects.
I assume this is a MutableRectangle since the Rectange in dart:math is unmodifiable.
That class indeed does not have a way to clone the values of another rectangle, so you have to copy each of them. I would use a cascade for that:
_rect
..left = _resetRect.left
..top = _resetRect.top
..width = _resetRect.width
..height = _resetRect.height;
Alternatively, if it happens often enough, you can create a helper function:
void copyRectangle(MutableRectangle target, Rectangle source) {
target
..left = source.left
..top = source.top
..width = source.width
..height = source.height;
}
I am trying to generate multiple pdfs into a single pdf, which I have achieved by using itextSharp , but while generating them few thing I came across,which are pointed below:
I am getting visible cell border just under image that i inserted .
Bottom image taking a space which flicks the image into another page, with extra visible border.
Also the paragraph didn't align to center.
Apart from these I also need that the text(in paragraph)comes from view(this code is doing in MVC).
How to solve these errors? Below is my code:
public byte[] GetPDF(string pHTML)
{
byte[] bPDF = null;
MemoryStream ms = new MemoryStream();
TextReader txtReader = new StringReader(pHTML);
//Rectangle pagesize = new Rectangle(864.0f, 1152.0f);
Document doc = new Document(PageSize.NOTE);
string path = Server.MapPath("PDFs");
PdfWriter oPdfWriter = PdfWriter.GetInstance(doc, ms);
HTMLWorker htmlWorker = new HTMLWorker(doc);
doc.Open();
for (int i = 1; i <= 5; i++)
{
doc.NewPage();
PdfPTable table= new PdfPTable(1);
table.TotalWidth = 500f;
table.LockedWidth = true;
table.HorizontalAlignment = 0;
table.DefaultCell.Border = Rectangle.NO_BORDER;
Image imageTopURL = Image.GetInstance("Top.PNG");
PdfPCell imgTopCell = new PdfPCell(imageTopURL);
Paragraph p = new Paragraph("XYZ", new Font(Font.FontFamily.COURIER, 32f, Font.UNDERLINE));
p.Alignment = Element.ALIGN_CENTER;
table.AddCell(imgTopCell);
table.AddCell(p);
Image imageMidURL = Image.GetInstance("Mid.PNG");
PdfPCell imgMidCell = new PdfPCell(imageMidURL);
Paragraph p1 = new Paragraph("ABC", new Font(Font.FontFamily.HELVETICA, 29f, Font.ITALIC));
p1.Alignment = Element.ALIGN_CENTER;
table.AddCell(imgMidCell);
imgMidCell.Border = 0;
table.AddCell(p1);
Image imageBotURL = Image.GetInstance("Bottom.PNG");
PdfPCell imgBotCell = new PdfPCell(imageBotURL);
table.AddCell(imgBotCell);
imageTopURL.ScaleAbsolute(505f, 270f);
imageMidURL.ScaleAbsolute(590f, 100f);
imageBotURL.ScaleAbsolute(505f, 170f);
doc.Open();
doc.Add(table);
htmlWorker.StartDocument();
htmlWorker.Parse(txtReader);
htmlWorker.EndDocument();
}
htmlWorker.Close();
doc.Close();
doc.Close();
bPDF = ms.ToArray();
return bPDF;
}
You are telling the table that default cells shouldn't have a border:
table.DefaultCell.Border = Rectangle.NO_BORDER;
This means that PdfPCell instances that are created implicitly won't get a border. For instance: if you do:
table.AddCell("Implicit cell creation");
Then that cell won't get a border.
However: you are creating a cell explicitly:
PdfPCell imgTopCell = new PdfPCell(imageTopURL);
In this case, the DefaultCell is never used. It is very normal that imgTopCell has a border. If you don't want a border for imgTopCell, you need to define the Border of imgTopCell like this:
imgTopCell.Border = Rectangle.NO_BORDER;
Regarding the alignment: it seems that you didn't read about the difference between text mode and composite mode. Please read the documentation, for instance:
Why does ColumnText ignore the horizontal alignment?
How to right-align text in a PdfPCell?
and many other FAQ entries about text mode and composite mode.
You are making a number of newbie mistakes that can all be fixed by reading the documentation. You have too many questions in one post. Please create new questions if my answer didn't solve every single of your problems. I see at least two more questions in your post (your question should actually be closed with as reason "Too broad").
Update:
In your comment, you added the following code snippet:
table.AddCell(new Paragraph(data.EmpName, new Font(Font.FontFamily.COURIER, 32f, Font.BOLD)));
You want to center this text.
First, let me explain that you are using the AddCell() method with a Paragraph as parameter. This doesn't really make sense as the Paragraph will be treated as a Phrase. You can as well write:
table.DefaultCell.HorizontalAlignment = Element.ALIGN_CENTER ;
table.AddCell(new Phrase(data.EmpName, new Font(Font.FontFamily.COURIER, 32f, Font.BOLD)));
When you are passing a Phrase to the AddCell() method, you are
using text mode (the properties of the cell prevail over the properties of its elements), and
you are asking iTextSharp to create a PdfPCell.
In this case, iTextSharp will look at the DefaultCell and use the properties of that cell to create a new cell. If you want to center the content of that new cell, you need to define this at the level of the DefaultCell. All of this is explained in my answer to the following questions:
Why doesn't getDefaultCell().setBorder(PdfPCell.NO_BORDER) have any effect?
What is the PdfPTable.DefaultCell property used for?
I've searched through all of the documentation that I can find for Farseer, and cannot find how to use BodyDef / FixtureDef in my projects. Have these been renamed to something else when they were ported over from Box2D?
My main concern is accomplishing something similar to the following:
FixtureDef fdef;
fdef.isSensor = true;
Although Farseer Physics has origins in Box2D, it is not an exact port of it. It has some similarities but does things it's own way (more familiar with C# programmers I guess). It doesn't use Def classes. I believe the following 2 examples are equivalent:
C++
// create a body
b2BodyDef bodyDef;
bodyDef.type = b2_dynamicBody;
bodyDef.position.Set(-10, 20);
b2Body* body = world->CreateBody(&bodyDef);
// create a shape
b2CircleShape circleShape;
circleShape.m_radius = 0.5f;
// create a fixture
b2FixtureDef myFixtureDef;
myFixtureDef.shape = &circleShape;
body->CreateFixture(&myFixtureDef);
C#
// create a body
var body = world.CreateBody();
body.BodyType = BodyType.Dynamic;
body.Position = new Vector2(-10, 20);
// create a shape
var circleShape = new CircleShape(0.5f);
// create a fixture
var fixture = body.CreateFixture(circleShape);
As you can see from the body, the main difference is that you set the properties after creation on the actual instance rather than a def class.
Farseer Physics also makes use of handy Factory classes. Take a look at the documentation for more information.
https://farseerphysics.codeplex.com/documentation
So I am working on a project using F# for some SVG line manipulations.
I thought it would be good to represent color an RGB value as a tuple (R,G,B). It just made sense to me. Well since my project involves generating SVG lines in a loop. I decided to have a color offset, conveniently also represented in a tuple (Roffset, Goffset, Boffset)
An offset in this case represents how much each line differs from the previous.
I got to a point where I needed to add the tuples. I thought since they were of the same dimensions and types, it would be fine. But apparently not. I also checked the MSDN on tuples, but I did not find anything about how to add them or combine them.
Here is what I tried. Bear in mind I tried to omit as much irrelevant code as possible since this is a long class definition with LOTS of members.
type lineSet ( 10+ params omitted ,count, colorOff :byte*byte*byte, color :byte*byte*byte ,strokeWid , strokeWidthOff ) =
member val Color = color with get, set
member val ColorOffset = colorOff with get, set
member val lineCount = count with get, set
interface DrawingInterfaces.IRepresentable_SVG with
member __.getSVGRepresenation() =
let mutable currentColor = __.Color
for i in 1..__.lineCount do
currentColor <- currentColor + __.ColorOffset
That last line of code is what I wanted to do. However, it appears you cannot add tuples directly.
I also need a way to clamp the result so it cannot go over 255, but I suspect a simple try with block will do the trick. OR I could let the params take a type int*int*int and just use an if to reset it back to 255 each time.
As I mentioned in the comments, the clamping function in your code does not actually work - you need to convert the numbers to integers before doing the addition (and then you can check if the integer is greater than 255). You can do something like this:
let addClamp (a:byte) (b:byte) =
let r = int a + int b
if r > 255 then 255uy else byte r
Also, if you work with colors, then it might make sense to define a custom color type rather than passing colors around as tuples. That way, you can also define + on colors (with clamping) and it will make your code simpler (but still, 10 constructor arguments is a bit scary, so I'd try to think if there is a way to simplify that a bit). A color type might look like this:
type Color(r:byte, g:byte, b:byte) =
static let addClamp (a:byte) (b:byte) =
let r = int a + int b
if r > 255 then 255uy else byte r
member x.R = r
member x.B = b
member x.G = g
static member (+) (c1:Color, c2:Color) =
Color(addClamp c1.R c2.R, addClamp c1.G c2.G,addClamp c1.B c2.B)
Using the type, you can then add colors pretty easily and do not have to add clamping each time you need to do that. For example:
Color(255uy, 0uy, 0uy) + Color(1uy, 0uy, 0uy)
But I still think you could make the code more readable and more composable by refactoring some of the visual properties (like stroke & color) to a separate type and then just pass that to LineSet. This way you won't have 10+ parameters to a constructor and your code will probably be more flexible too.
Here is a modified version of your code which I think is a bit nicer
let add3DbyteTuples (tuple1:byte*byte*byte , tuple2:byte*byte*byte) =
let inline intify (a,b,c) = int a,int b,int c
let inline tripleadd (a,b,c) (d,e,f) = a+d,b+e,c+f
let clamp a = if a > 255 then 255 else a
let R,G,B = tripleadd (intify tuple1) (intify tuple2)
clamp R,clamp G,clamp B
I saw the syntax below in some example code and am not sure I understand it.
CGRect imageRect = (CGRect){.size = baseImage.size};
Is this simply a shorthand way of initializing a CGRect equivalent to:
CGRect imageRect = CGRectMake(0,0,baseImage.size.width, baseImage.size.height);
Is there any benefit to this syntax aside from slightly less typing?
That's C99 initializer syntax. You can use it with any structure.
The main advantage to an Objective-C is that it gives you some very Objective-C like syntax, where the fields are close to the values rather than implied by positioning. (That's not to say this is intentionally similar, or that it's the only advantage. But it is nice.)
It's sometimes slightly more typing, but I use it everywhere now.
Consider:
CGRect a = CGRectMake(a+c/2, b+d/2, c, d);
In order to understand this, you need to understand the order of the parameters. You also need to be able to catch the commas easily with your eyes. In this case, that's pretty easy, but if the expressions were more complicated you'd probably be storing them in a temporary variable first.
The C99 way:
CGRect a = (CGRect){
.origin.x = a+c/2,
.origin.y = b+d/2,
.size.width = c,
.size.height = d
};
It's longer, but it's more explicit. It's also very easy to follow what is assigned to what, no matter how long the expression are. It's also more like an Objective-C method. After all, if CGRect was a class, it would probably look like this:
CGRect *a = [[CGRect alloc] initWithOriginX:x originY:y width:w height:h];
You can also do things like this:
CGRect a = (CGRect){
.origin = myOrigin,
.size = computedSize
};
Here, you're building a rectangle using a CGPoint and CGSize. The compiler understands that .origin expects a CGPoint, and .size expects a CGSize. You've provided that. All's gravy.
The equivalent code would be CGRectMake(myOrigin.x, myOrigin.y, size.width, size.height). By using CGRectMake you're no longer expressing the same kind of meaning to the compiler. It can't stop you from assigning part of the size to the origin. It also won't stop you from assigning the width to the height. It doesn't even give you a good clue about which is the X and Y; if you've used APIs that provide vertical coordinates first, you'll get it wrong.
You can assign part from a structure and part from floats as well:
CGRect a = (CGRect){
.origin = myOrigin,
.size.width = c,
.size.height = d
};
The CGRectMake function predates C99. I have no evidence to this effect, but I think if C99 had come first CGRectMake probably wouldn't exist at all; it's the sort of crusty function you write when your language has no direct way to perform the initialization. But now it does.
Basically, if you use it for a while, you'll probably come to prefer C99 syntax. It's more explicit, more flexible, more Objective-C-like and harder to screw up.
Unfortunately, as of 4.6 Xcode will not autocomplete structure field names when in the C99 field initializer list.
This is not just shorthand syntax but is also useful when you want to change only the size and not the origin in CGRect and vice versa.
Eg : I want to change only the size and the position has a complicated syntax and I dont want to change it. Noramlly, I would do
CGRect imageRect = CGRectMake(sprite.origin.x,sprite.origin.y,40, 60);
With the other syntax i would do
CGRect imageRect = (CGRect){.size = sprite.size};
also we can directy use add, subtract and multiply methods
eg.
CGRect imageRect = (CGRect){.size = ccpAdd(sprite.size,addsize)};
Hope this helps
it looks like C99 / GCC style initializing http://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html