Index: /CKEditor/trunk/_source/core/config.js
===================================================================
--- /CKEditor/trunk/_source/core/config.js	(revision 3117)
+++ /CKEditor/trunk/_source/core/config.js	(revision 3118)
@@ -148,5 +148,5 @@
 	 */
 
-	plugins : 'basicstyles,blockquote,button,clipboard,elementspath,find,flash,format,forms,horizontalrule,htmldataprocessor,image,indent,justify,keystrokes,link,list,newpage,pagebreak,pastefromword,pastetext,preview,print,removeformat,smiley,showblocks,sourcearea,table,specialchar,tab,templates,toolbar,undo,wysiwygarea',
+	plugins : 'basicstyles,blockquote,button,clipboard,elementspath,find,flash,font,format,forms,horizontalrule,htmldataprocessor,image,indent,justify,keystrokes,link,list,newpage,pagebreak,pastefromword,pastetext,preview,print,removeformat,smiley,showblocks,sourcearea,table,specialchar,tab,templates,toolbar,undo,wysiwygarea',
 
 	/**
Index: /CKEditor/trunk/_source/core/tools.js
===================================================================
--- /CKEditor/trunk/_source/core/tools.js	(revision 3117)
+++ /CKEditor/trunk/_source/core/tools.js	(revision 3118)
@@ -35,4 +35,45 @@
 
 			return true;
+		},
+
+		/**
+		 * Creates a deep copy of an object.
+		 * Attention: there is no support for deep copy of Array properties and
+		 * for recursive references.
+		 * @param {Object} object The object to be cloned.
+		 * @returns {Object} The object clone.
+		 * @example
+		 * var obj =
+		 *     {
+		 *         name : 'John',
+		 *         cars :
+		 *             {
+		 *                 Mercedes : { color : 'blue' },
+		 *                 Porsche : { color : 'red' }
+		 *             }
+		 *     };
+		 * var clone = CKEDITOR.tools.clone( obj );
+		 * clone.name = 'Paul';
+		 * clone.cars.Porsche.color = 'silver';
+		 * alert( obj.name );	// John
+		 * alert( clone.name );	// Paul
+		 * alert( obj.cars.Porsche.color );	// red
+		 * alert( clone.cars.Porsche.color );	// silver
+		 */
+		clone : function( object )
+		{
+			var clone = {};
+
+			for ( var propertyName in object )
+			{
+				var property = object[ propertyName ];
+
+				if ( typeof property == 'object' )
+					property = this.clone( property );
+
+				clone[ propertyName ] = property;
+			}
+
+			return clone;
 		},
 
Index: /CKEditor/trunk/_source/lang/en.js
===================================================================
--- /CKEditor/trunk/_source/lang/en.js	(revision 3117)
+++ /CKEditor/trunk/_source/lang/en.js	(revision 3118)
@@ -454,4 +454,16 @@
 		tag_h6 : 'Heading 6',
 		tag_div : 'Normal (DIV)'
+	},
+
+	font :
+	{
+		label : 'Font',
+		panelTitle : 'Font Style'
+	},
+
+	fontSize :
+	{
+		label : 'Size',
+		panelTitle : 'Font Size'
 	}
 };
Index: /CKEditor/trunk/_source/plugins/font/plugin.js
===================================================================
--- /CKEditor/trunk/_source/plugins/font/plugin.js	(revision 3118)
+++ /CKEditor/trunk/_source/plugins/font/plugin.js	(revision 3118)
@@ -0,0 +1,160 @@
+/*
+Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.html or http://ckeditor.com/license
+*/
+
+(function()
+{
+	function addCombo( editor, comboName, styleType, lang, entries, defaultLabel, styleDefinition )
+	{
+		var config = editor.config;
+		var saveRanges;
+
+		// Gets the list of fonts from the settings.
+		var names = entries.split( ';' ),
+			values = [];
+
+		// Create style objects for all fonts.
+		var styles = {};
+		for ( var i = 0 ; i < names.length ; i++ )
+		{
+			var vars = {};
+			var parts = names[ i ].split( '/' );
+
+			var name = names[ i ] = parts[ 0 ];
+			vars[ styleType ] = values[ i ] = parts[ 1 ] || name;
+
+			styles[ name ] = new CKEDITOR.style( styleDefinition, vars );
+		}
+
+		editor.ui.addRichCombo( comboName,
+			{
+				label : lang.label,
+				title : lang.panelTitle,
+				className : 'cke_' + ( styleType == 'size' ? 'fontSize' : 'font' ),
+				multiSelect : false,
+
+				panel :
+				{
+					css : [ config.contentsCss, CKEDITOR.getUrl( editor.skinPath + 'editor.css' ) ],
+					className : 'cke_skin_default'
+				},
+
+				init : function()
+				{
+					this.startGroup( lang.panelTitle );
+
+					for ( var i = 0 ; i < names.length ; i++ )
+					{
+						var name = names[ i ];
+
+						// Add the tag entry to the panel list.
+						this.add( name, '<span style="font-' + styleType + ':' + values[ i ] + '">' + name + '</span>', name );
+					}
+				},
+
+				onClick : function( value )
+				{
+					editor.focus();
+
+					if ( saveRanges )
+					{
+						editor.getSelection().selectRanges( saveRanges );
+						saveRanges = false;
+					}
+
+					var style = styles[ value ]
+
+					if ( this.getValue() == value )
+						style.remove( editor.document );
+					else
+						style.apply( editor.document );
+				},
+
+				onRender : function()
+				{
+					editor.on( 'selectionChange', function( ev )
+						{
+							var currentValue = this.getValue();
+
+							var elementPath = ev.data.path;
+
+							for ( var value in styles )
+							{
+								if ( styles[ value ].checkActive( elementPath ) )
+								{
+									if ( value != currentValue )
+										this.setValue( value );
+									return;
+								}
+							}
+
+							// If no styles match, just empty it.
+							this.setValue( '', defaultLabel );
+						},
+						this);
+				},
+
+				onOpen : function()
+				{
+					if ( CKEDITOR.env.ie )
+					{
+						editor.focus();
+						saveRanges = editor.getSelection().getRanges();
+					}
+				},
+
+				onClose : function()
+				{
+					saveRanges = null;
+				}
+			});
+	}
+
+	CKEDITOR.plugins.add( 'font',
+	{
+		requires : [ 'richcombo', 'styles' ],
+
+		init : function( editor )
+		{
+			var config = editor.config;
+
+			addCombo( editor, 'Font', 'family', editor.lang.font, config.font_names, config.font_defaultLabel, config.font_style );
+			addCombo( editor, 'FontSize', 'size', editor.lang.fontSize, config.fontSize_sizes, config.fontSize_defaultLabel, config.fontSize_style );
+		}
+	});
+})();
+
+// Font settings.
+
+CKEDITOR.config.font_names =
+	'Arial/Arial, Helvetica, sans-serif;' +
+	'Comic Sans MS/Comic Sans MS, cursive;' +
+	'Courier New/Courier New, Courier, monospace;' +
+	'Georgia/Georgia, serif;' +
+	'Lucida Sans Unicode/Lucida Sans Unicode, Lucida Grande, sans-serif;' +
+	'Tahoma/Tahoma, Geneva, sans-serif;' +
+	'Times New Roman/Times New Roman, Times, serif;' +
+	'Trebuchet MS/Trebuchet MS, Helvetica, sans-serif;' +
+	'Verdana/Verdana, Geneva, sans-serif';
+
+CKEDITOR.config.font_defaultLabel = ''
+CKEDITOR.config.font_style =
+	{
+		element		: 'span',
+		styles		: { 'font-family' : '#(family)' },
+		overrides	: [ { element : 'font', attributes : { 'face' : null } } ]
+	};
+
+// Font Size setting.
+
+CKEDITOR.config.fontSize_sizes =
+	'8/8px;9/9px;10/10px;11/11px;12/12px;14/14px;16/16px;18/18px;20/20px;22/22px;24/24px;26/26px;28/28px;36/36px;48/48px;72/72px';
+
+CKEDITOR.config.fontSize_defaultLabel = ''
+CKEDITOR.config.fontSize_style =
+	{
+		element		: 'span',
+		styles		: { 'font-size' : '#(size)' },
+		overrides	: [ { element : 'font', attributes : { 'face' : null } } ]
+	};
Index: /CKEditor/trunk/_source/plugins/format/plugin.js
===================================================================
--- /CKEditor/trunk/_source/plugins/format/plugin.js	(revision 3117)
+++ /CKEditor/trunk/_source/plugins/format/plugin.js	(revision 3118)
@@ -6,5 +6,5 @@
 CKEDITOR.plugins.add( 'format',
 {
-	requires : [ 'richcombo' ],
+	requires : [ 'richcombo', 'styles' ],
 
 	init : function( editor )
@@ -16,5 +16,5 @@
 
 		// Gets the list of tags from the settings.
-		var tags = config.format_tags.split( ',' );
+		var tags = config.format_tags.split( ';' );
 
 		// Create style objects for all defined styles.
@@ -106,5 +106,5 @@
 });
 
-CKEDITOR.config.format_tags = 'p,h1,h2,h3,h4,h5,h6,pre,address,div';
+CKEDITOR.config.format_tags = 'p;h1;h2;h3;h4;h5;h6;pre;address;div';
 
 CKEDITOR.config.format_p		= { element : 'p' };
Index: /CKEditor/trunk/_source/plugins/richcombo/plugin.js
===================================================================
--- /CKEditor/trunk/_source/plugins/richcombo/plugin.js	(revision 3117)
+++ /CKEditor/trunk/_source/plugins/richcombo/plugin.js	(revision 3118)
@@ -199,4 +199,12 @@
 			list.onClick = function( value, marked )
 				{
+					// Move the focus to the main windows, otherwise it will stay
+					// into the floating panel, even if invisible, and Safari and
+					// Opera will go a bit crazy.
+					me.document.getWindow().focus();
+
+					if ( me.onClick )
+						me.onClick.call( me, value, marked );
+
 					if ( marked )
 						me.setValue( value, me._.items[ value ] );
@@ -204,12 +212,4 @@
 						me.setValue( '' );
 
-					// Move the focus to the main windows, otherwise it will stay
-					// into the floating panel, even if invisible, and Safari and
-					// Opera will go a bit crazy.
-					me.document.getWindow().focus();
-
-					if ( me.onClick )
-						me.onClick.call( me, value, marked );
-
 					panel.hide();
 				};
Index: /CKEditor/trunk/_source/plugins/toolbar/plugin.js
===================================================================
--- /CKEditor/trunk/_source/plugins/toolbar/plugin.js	(revision 3117)
+++ /CKEditor/trunk/_source/plugins/toolbar/plugin.js	(revision 3118)
@@ -222,4 +222,5 @@
 	['Link','Unlink','Anchor'],	['Image','Flash','Table','HorizontalRule','Smiley','SpecialChar','PageBreak'],
 	'/',
-	['Format'],	['ShowBlocks']
+	['Format','Font','FontSize'],
+	['ShowBlocks']
 ];
Index: /CKEditor/trunk/_source/skins/default/editor.css
===================================================================
--- /CKEditor/trunk/_source/skins/default/editor.css	(revision 3117)
+++ /CKEditor/trunk/_source/skins/default/editor.css	(revision 3118)
@@ -10,4 +10,5 @@
 @import url("richcombo.css");
 @import url("elementspath.css");
+@import url("presets.css");
 
 /* Restore the container visibility */
Index: /CKEditor/trunk/_source/skins/default/panel.css
===================================================================
--- /CKEditor/trunk/_source/skins/default/panel.css	(revision 3117)
+++ /CKEditor/trunk/_source/skins/default/panel.css	(revision 3118)
@@ -23,10 +23,4 @@
 	-webkit-border-top-right-radius: 3px;
 	border-top-right-radius: 3px;
-}
-
-.cke_skin_default.cke_panel.cke_format
-{
-	width: 150px;
-	height: 170px;
 }
 
Index: /CKEditor/trunk/_source/skins/default/presets.css
===================================================================
--- /CKEditor/trunk/_source/skins/default/presets.css	(revision 3118)
+++ /CKEditor/trunk/_source/skins/default/presets.css	(revision 3118)
@@ -0,0 +1,30 @@
+/*
+Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.html or http://ckeditor.com/license
+*/
+
+/* "Format" panel size */
+.cke_skin_default.cke_panel.cke_format
+{
+	width: 150px;
+	height: 170px;
+}
+
+/* "Font" panel size */
+.cke_skin_default.cke_panel.cke_font
+{
+	width: 150px;
+	height: 170px;
+}
+
+/* "Font Size" panel size */
+.cke_skin_default.cke_panel.cke_fontSize
+{
+	height: 170px;
+}
+
+/* "Font Size" combo width */
+.cke_skin_default .cke_fontSize .cke_text
+{
+	width: 20px;
+}
Index: /CKEditor/trunk/_source/tests/core/tools.html
===================================================================
--- /CKEditor/trunk/_source/tests/core/tools.html	(revision 3117)
+++ /CKEditor/trunk/_source/tests/core/tools.html	(revision 3118)
@@ -126,4 +126,28 @@
 		},
 
+		test_clone : function()
+		{
+			var obj =
+			{
+				name : 'John',
+				cars :
+				{
+					Mercedes : { color : 'blue' },
+					Porsche : { color : 'red' }
+				}
+			};
+
+			var clone = CKEDITOR.tools.clone( obj );
+
+			clone.name = 'Paul';
+			clone.cars.Porsche.color = 'silver';
+
+			assert.areSame( 'John', obj.name );
+			assert.areSame( 'Paul', clone.name );
+
+			assert.areSame( 'red', obj.cars.Porsche.color );
+			assert.areSame( 'silver', clone.cars.Porsche.color );
+		},
+
 		name : document.title
 	};
