|
Guys, I thought about your decisions already to use thumbnails instead of main image. I actually tried to work with small images, but the size of image at which i got accepting filter performance was too small. I have to use an image cropping tool too and that is the main cause why I don't want to use small images. Maybe somebody knows some third party filters with good performance or how this functions realized in Photoshop or Vista? I really don't know how to use exposure features for large images. Maybe it can be possible to involve some graphic card possibility or something else...
|
|
|
|
|
Hey guys.
I'm working on a syntax highlighter, in which my current method of highlighting (RichTextBox + TextChanged + Regular Expressions) has become to unsmooth and slow. I've literally spent days searching for other methods, and the best one I've found was the ICSharpCode.TextEditor, however when taking I look into it I was unable to find the code in which it highlights its code.
So any of you guys have some experience here? Any help'd be appreciated, but code examples more.
PS: my current highlighter is about 10 seconds about highlighting 2100 lines of code, where ICSharpCode.TextEditor is about 1 - 2 seconds.
Theo
|
|
|
|
|
Hi,
You are doing it in the logical way, just like most people asking questions here about the subject; however IMO it is completely inappropriate for a range of reasons:
1. an RTB is a stupid control that doesn't scale well as it holds all the text as one large string, so it may or may not work well for 100 lines, it is bound to fail at serving you right for 10,000 lines of text. I did my own editor based on a Panel; that takes:
- keyboard and mouse handlers to do the editing myself;
- a Paint handler using Graphics.DrawString.
2. Regex is a powerful tool with big performance hits; I tend not to use it, except for offering complex search/replace capabilities in the hands of your apps' users. For maximum speed, code the search and replace stuff yourself, using string methods such as IndexOf and Contains.
3. Finally, my syntax colorizer is inside my Paint handler: it skips all the lines that are scrolled over, then parses just the 20 to 40 lines that are visible, and stops when it reaches the last visible line. In order to correctly skip the beginning of the text, my data structures are such that I keep a few flags for each line of text, related to opening and closing of multi-line comments; the idea is I can start parsing a (modified) line without the need to parse again all previous lines.
The net result is:
- I have an editor that works the way I like it;
- it syntax-colorizes instantaneously;
- when I select some text, it immediately highlights identical strings in the visible part of the text (something extremely useful Visual Studio doesn't do for me).
My advice to you, assuming you will want to keep the RTB, is to replace the Regex parts by string operations.
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
|
|
|
|
|
Thanks for the great reply Luc! It was really helpful!
That idea with the Panel sounds very cool, you still got the source code? I'd love to take a look at it.
And really, I don't really mind if I need to replace the RTB, if it's slow and bad, I'll anytime replace it with something better.
I hope you still have that source, it'd help me soooo much.
Oh yeah, did I mention that I also used StringBuilders in my highlighter? I mean, to build the RTF.
Thanks,
Theo
modified on Tuesday, July 14, 2009 3:01 PM
|
|
|
|
|
Hi,
I created my own Explorer+IDE (it supports a build process for a range of microprocessors, each using different compilers and linkers); and the editor is a big chunk of that. It isn't some small piece of code I can easily carve out and hand over, if I would like to do so, which I don't. I have my own way of dealing with file systems, with logging, with app settings, etc. One of the strong points at the functional level is the find capabilities, which exceed anything I have ever seen in another IDE.
The entire app exceeds 70000 lines of code right now (in more than 250 files), and it continues to grow as I add features. The editor panel isn't a real control, I didn't use many controls anyhow, they tend to slow down things too much. The basic philosophy is to use existing classes/controls when they fit perfectly, and create my own when they don't. So I refuse to fight against shortcomings of say a RichTextBox, I create what I need from scratch. It takes a while, but it pays of.
So in summary I can give you my view, my advice, but not much useful code.
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
|
|
|
|
|
OK, I'll take that as a no
But anyways, I pretty think I know what to do with the Panel to make it look like the RichTextBox:
- 3D borders.
- Window -colored background.
- When user hovers over the Panel, change cursor.
- When user clicks the Panel, create a custom cursor by using the |, using a timer to display and hide it.
- When user begins to write, have a handler that handles KeyPress (KeyDown maybe?) which draws (?) the text. Have the whole typed text in a string and have an array with all the lines in it.
Is it something like that? You sure you can't just send me the extended Panel Class/Control/Component (?)? Maybe just a little sneakpeak? If not, can I have your MSN or Skype or anything really so I can instant message you when I'm in trouble?
Theo
|
|
|
|
|
You're pretty close, except for the details:
- I didn't want to look it exactly like an RTB, however that is not a primary concern;
- I draw my own cursor, I don't use a Windows cursor; I want it to be located and sized exactly up to the pixel, all my cursors have to be in sync, and the cursor resizes when I resize my fonts;
- I need KeyDown, KeyPress and KeyUp events for functional reasons;
- each line of text becomes a little object holding a string, and some administrative information;
- I keep textlines in a List obviously, not an array.
And you are free to post questions, I am watching several forums including this one. So there is a good chance you will get my reply.
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
modified on Wednesday, July 15, 2009 6:22 AM
|
|
|
|
|
You don't got some kind of instant messager? I'd be much easier for me.
Ehhh, I'm kinda stuck at the Caret thingy... How do I convert text locations to Points?
Code:
namespace Storm.TextBox.Document
{
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
public class Caret : Control
{
#region Members
private Timer caretTimer = new Timer();
private int Interval = 50;
private string caretString = "|";
private Font caretFont = new Font(new Font("Courier New", 9.25f), FontStyle.Bold);
private Color caretColor = SystemColors.ControlText;
private bool caretDisplay = true;
private Point caretPos = new Point(-1, -1);
private Size caretSize;
#endregion
#region Properties
public Font CaretFont
{
get { return caretFont; }
set { caretFont = value; }
}
public string DisplayString
{
get { return caretString; }
set { caretString = value; }
}
public int CaretInterval
{
get { return Interval; }
set { Interval = value; }
}
#endregion
#region Methods
private void onTick(object sender, EventArgs e)
{
caretDisplay = !caretDisplay;
Invalidate();
}
private void DrawCaret(Graphics g)
{
if (caretDisplay == true)
{
Rectangle r = new Rectangle(caretPos, caretSize);
ControlPaint.DrawStringDisabled(g, caretString, caretFont, caretColor, r, TextFormatFlags.Default);
}
}
private void onPaint(object sender, PaintEventArgs e)
{
DrawCaret(e.Graphics);
}
#endregion
public Caret()
{
Paint += new PaintEventHandler(onPaint);
caretTimer.Enabled = true;
caretTimer.Tick += new EventHandler(onTick);
caretTimer.Start();
}
}
}
|
|
|
|
|
No, I don't do chat, twitter, and the like.
IIRC monospaced fonts such as Courier New always have integral character widths; so what I probably do is int charwidth=(int)(0.5+Graphics.MeasureString(someLongString).Width/someLongString.Length); once, then use that charwidth to map column numbers to/from pixel numbers.
If the above were incorrect, changing the fontsize slightly would be sufficient to make it hold true.
BTW: for proportional fonts things are much more complex, since then you have to really convert each and every position on its own merits.
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
|
|
|
|
|
Hmm... someLongString being the... what?
> charwidth to map column numbers to/from pixel numbers.
I don't get that, sorry :s
|
|
|
|
|
just a long string with arbitrary content; although it probably does not matter much since all characters are assumed to have equal width, so a short string should give the same result in theory.
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
|
|
|
|
|
Hmm, that is weird, it says MeasureString takes 4 arguments. What should I put in the others?
Could you also explain this: charwidth to map column numbers to/from pixel numbers. ?
|
|
|
|
|
Yes, I only gave pseudo-code to convey the idea.
For the details read the documentation, that is what it is for. I will not hold your hand all the way.
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
|
|
|
|
|
Hmm, okay I figured it out
I was thinking, since I'm making the Document class..
Wouldn't it be smarter to have a Dictionary<int, string=""> than a List<string>? Since I'm creating a method "UpdateLine" that takes (int lineNum, string newLine)? The reason I'm asking is because I'm not sure if it's the most efficient way.
Really, I now it's kinda disturbing that I ask so much, but I am totally new to making this custom-Caret-Cursor-textpoint-to-pixel-thingy, I know nothing about it. I simply always used the default Windows controls or inheritted them in my own. Please bear with me
The thing about the map column thing... should I simply just, when the Document is updated, add the charWidth to the current caret point (of course substract when the user hit backspace) ? That is what seems most logical to me.
|
|
|
|
|
Hi,
having a method UpdateLine(int lineNum, string newLine) seems appropriate.
you don't need a Dictionary for that, most collections support indexing, so you could have a List<string> textLines and then perform textLines[ineNum]=newLine; as if it were an array, except I guess for adding lines beyond the current end of the list, then you would need textLines.Add(newLine);
I suggest you read up on indexers[^].
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
|
|
|
|
|
OK, this is great, I think I'm on the right track now. I got it to display the Cursor X and Y when the TextEditor recieves focus, so I suppose I should convert those values into row and columns in the text, right? And if the the row and column values are invalid, jump to the last available row and column?
I think I get everything, however, how would I convert X and Y values into row and columns? You got a formula for that I should I try myself?
Thanks for everything so far!
|
|
|
|
|
Hi,
with monospaced fonts, the formula are ver simple:
xPixel=(textColumnNumber-horizontalScrollCount)*textCharacterWidth;
yPixel=(textLineNumber-verticalScrollCount)*textLineHeight;
which is assuming all characters have same width and height, and all scrolling is by integral lines and characters. Which I prefer anyway.
The above are text position to screen position (as for displaying stuff); invert them for editing (mouse to text).
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
|
|
|
|
|
Hmm, like this?
colNum = (Cursor.Position.X + this.stormParent.HorizontalScroll.Value) / charWidth;<br />
rowNum = (Cursor.Position.Y + this.stormParent.VerticalScroll.Value) / charHeight;
Because that simply gives me the same values except in minus. (261 290 becomes -261 -290 for example)
I feel sooooo stupid :s
|
|
|
|
|
Vestras wrote: like this?
obviously not. Put those gray cells to work!
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
|
|
|
|
|
Ahh I finally figured out what the thing was! Yours is linenumber, mine isn't.
But ehh... don't I need to know the col and row to figure out the line number? >__<
Hmm... and wouldn't the textLineHeight be the same as charHeight?
|
|
|
|
|
Vestras wrote: wouldn't the textLineHeight be the same as charHeight?
maybe, maybe not.
when you do Graphics.DrawString("abc",...) the font is in charge of the character spacing.
when you paint individual text lines (or parts thereof as you are going to perform syntax coloring), you are in charge of the vertical line distance, it does not directly relate to the font height (whatever that is) as long as it is large enough.
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
|
|
|
|
|
OK, I can't figure it out... my gray brain cells are dead
Can't you, please, post the correct formula? I tried everything (obviously not, but I tried what my brain could make up)
Gosh...
|
|
|
|
|
Sorry I won't.
This is what you shall do:
1. take pencil and paper
2. copy one formula exactly as it is (you are allowed shorter names, as long as they are clear)
3. locate the position of the unknown variable
4. copy the previous formula but now either add/subtract/multiply/divide by something on both sides (hence keeping the equality), so that the side where the unknown is becomes simpler
5. repeat step 4 until you've got it.
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
|
|
|
|
|
OK I'll start from the beginning again...
Is this true?
xPixel = (textColumnNumber - horizontalScrollCount) * textCharacterWidth;
yPixel = (textLineNumber - verticalScrollCount) * textLineHeight;
______/\______ ___________/\__________
Unknown Vars Unknown Var(S)?
|
|
|
|
|
You choose a font size, hence you get a charwidth and a charheight; you choose a textLineHeight equal to or slightly larger than the charheight.
On (mouse) input you know xPixel and yPixel and want to know textLineNumber and textColumnNumber
on (display) output you know textLineNumber and textColumnNumber and want to know xPixel and yPixel.
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
|
|
|
|
|